3

这是我的设置。

我有一个 Main SherlockFragmentActivity。它用'sListFragments来回交换许多。FragmentTransaction为了指示加载,任何时候ListFragment加载我调用的数据:

setSupportProgressBarIndeterminateVisibility(true);

问题:

Activity上面提到的main第一次启动,或者用户离开去其他app过一段时间再重启这个的时候SherlockFragmentActivity貌似reloads,里面没有进度对话框ActionBar,白屏几秒,然后列表数据修复(长度取决于数据连接)。

这是一些补充代码:当主/基本Activity首次加载时,这是我在以下代码中做的第一件事onCreate()

// Set up Main Screen
FragmentTransaction t2 = this.getSupportFragmentManager().beginTransaction();
SherlockListFragment mainFrag = new FollowingFragment();
t2.replace(R.id.main_frag, mainFrag);
t2.commit();

FollowingFragment是在这种情况下始终加载的那个。它包含一个ListView和一个AsyncTask从数据库中提取的数据MySQL

我的问题:如何防止这种延迟?当用户长时间离开时,我如何处理维护数据?

4

4 回答 4

3

这是正常行为,发生这种情况是因为当您的应用程序在后台时,您的活动已被终止以节省其他应用程序的内存。当它回到前台时,系统会重新创建您的活动,这将重新创建您的片段。

但是如果你真的想避免重新创建你的片段,你可以在片段的 onCreate 方法中使用 setRetainInstance :

公共无效 setRetainInstance(布尔保留)

控制是否在 Activity 重新创建期间(例如从配置更改)保留片段实例。这只能与不在后台堆栈中的片段一起使用。如果设置,片段生命周期将在重新创建活动时略有不同:

onDestroy() 将不会被调用(但 onDetach() 仍然会被调用,因为片段正在与其当前活动分离)。onCreate(Bundle) 不会被调用,因为片段没有被重新创建。onAttach(Activity) 和 onActivityCreated(Bundle) 仍将被调用。

并在 FragmentActivity 的 onActivityCreated 方法中使用类似的东西:

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        FragmentManager fm = getFragmentManager();

        // Check to see if we have retained the worker fragment.
        mRetainableFragment = (RetainedFragment)fm.findFragmentByTag("fragmentTag");

        // If not retained (or first time running), we need to create it.
        if (mRetainableFragment == null) {
            mRetainableFragment = new RetainedFragment();
            // Tell it who it is working with.
            mRetainableFragment.setTargetFragment(this, 0);
            fm.beginTransaction().add(mRetainableFragment, "fragmentTag").commit();
        }
    }

但请注意,这应该只用于无头片段(没有 UI 的片段,即在 onCreateView 中返回 null,又名工作片段)。您仍然可以将此方法用于 UI 片段,但 google 不推荐使用此方法,在这种情况下,数据必须作为成员(字段)存储在您的活动中。如果 Bundle 类支持应该存储的数据,您可以使用 onSaveInstanceState() 方法将数据放入 Bundle,并在 onActivityCreated() 方法中检索该数据。

此外,这仅在片段未添加到后台堆栈时才有效。

于 2013-07-30T00:06:00.947 回答
1

当您的应用程序被杀死时,您将丢失活动状态和数据!我可以假设您的两种情况AsyncTask
1. 您正在从Webserver. 在这种情况下,我个人认为缓存您从中检索到的数据webserver是一个比实施更好的解决方案serializable
2. 您正在从本地数据库中提取大量数据(这会导致检索数据需要一些时间)。在这种情况下,我建议只检索您需要的数据,而不是更多!(例如,您可以检索 20 个项目,当用户滚动到末尾时ListView检索下一个 20 个项目)。此解决方案可帮助您的应用程序更快地检索数据。

PS:为了给你一个线索如何实现WebserviceModule缓存功能,我假设它位于你的AsyncTask,你可以保存 SDCard 中的每个响应webserver,每次你试图从 检索一些资源时webserver,你应该检查 SDCard 看看如果您的请求已经发送并缓存!对于每个请求,您都应该基于urlpost parameters识别缓存文件创建一个唯一的签名。

于 2013-07-31T18:41:54.717 回答
1

根据Activity 上的 Android 开发人员参考页面,您必须在调用之前请求进度条功能setSupportProgressBarIndeterminateVisibility()

requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);  
setSupportProgressBarIndeterminateVisibility(true);

另一个问题,重新加载片段,是由于 Android 杀死了你ListFragment,因此它们必须重新加载可以通过覆盖onSaveInstanceState(Bundle outState)和缓存你的数据来解决,以便在你的ListFragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if(savedInstanceState != null) {
        // retrieve data from Bundle here
    } else {
        // no data, we need to reload from network
    }

    // initialize your View here
}

但是,不能保证此方法一直运行(它不在 Fragment 生命周期中)。因此,您还应该确保缓存数据onPause()并使用它,而不是总是从网络连接加载。

@Override
public void onPause() {
    super.onPause();
    SharedPreferences prefs = getActivity().getSharedPreferences();
    SharedPreferences.Editor editor = prefs.edit();
    // put your data here using editor
    editor.commit();
}

然后,您可以通过检索并使用其他方法onCreateView()的实例来加载此数据。SharedPreferencesprefs.getString(String key)

于 2013-07-25T01:45:38.770 回答
0

当您在延长一段时间后恢复活动时,整个应用程序将重新启动。所以你不能依赖对象变量来保存数据。

因此,您可以避免延迟您已经提到在活动 onStop() 方法中将数据保存到某些本地存储。例如,共享偏好。

并且当您调用 onCreate() 时,检查您是否已保存数据并使用它(如果存在)(并清理以使下次“干净”启动),否则启动 asynctask。

于 2013-07-31T09:51:53.693 回答