我注意到使用Android Loaders和Fragments的奇怪情况.当我调整方向更改onLoadFinished后调用LoaderManager.initLoader()时(尽管文档建议我应该为此做好准备),但在此之后调用它两次.以下链接指向相同情况的Google群组中的帖子https://groups.google.com/forum/?fromgroups#!topic/android-developers/aA2vHYxSskU.我编写了示例应用程序,其中我只在Fragment.onActivityCreated()中初始化简单的Loader来检查是否会发生这种情况.有人注意到了吗?
查看LoaderCustomSupport(使用AsyncTaskLoader)和FragmentRetainInstanceSupport(使用Thread,几乎等同于AsyncTask)
两个例子都有以下相似之处.
但是,存在差异.
是否有任何指南或清单可以决定是否选择AsyncTaskLoader或AsyncTask来执行耗时的加载任务并将结果更新到Fragment的UI?
如果我错了,请纠正我.这是一个澄清问题,因为我没有看到它明确写在任何地方.
在Android 4中,您可以调用setRetainInstance(true)on Fragment以便在配置更改(这基本上意味着设备旋转)时,Fragment不会销毁java对象并且不会创建它的新实例.也就是说,保留了实例.
由于您不必处理和捆绑所有数据,因此它可以传递给新的(或)实例,只是再次进行非捆绑,因此这比Android 1-3更加理智且不那么令人愤怒.这基本上是你期望发生的事情,并且可以说它应该从一开始就如何起作用.onRetainNonConfigurationStateInstance()FragmentActivityActivity
通过setRetainInstance(true)视图也可以onCreateView()像您期望的那样在旋转时重新创建(被调用).我假设(未测试)资源解析(layoutvs layout-land)有效.
所以我的问题是双重的:
Activities从一开始为什么不喜欢这个.Fragment被无谓破坏并重新创建的轮换?因为我想不到任何.澄清我将如何做到:
class MyFragment extends Fragment
{
// All the data.
String mDataToDisplay;
// etc.
// All the views.
TextView mViewToDisplayItIn;
// etc.
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
mDataToDisplay = readFromSomeFileOrWhatever(); // Ignoring threading issues for now.
}
@Override
public View onCreateView(LayoutInflater inflater, …Run Code Online (Sandbox Code Playgroud) 我有一个主要的活动A,它使用CursorLoader来查询数据库.这是我在活动onCreate()方法中创建的:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
getSupportLoaderManager().initLoader(LOADER_MEASUREMENTS, null, A.this);
}
Run Code Online (Sandbox Code Playgroud)
Activity A还实现了CursorLoader的3个回调:
public Loader<Cursor> onCreateLoader(int loaderId, Bundle args)
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
public void onLoaderReset(Loader<Cursor> loader)
Run Code Online (Sandbox Code Playgroud)
当我旋转设备时,我看到正确的生命周期方法运行:
A.onPause()
A.onStop()
A.onDestroy()
A.onCreate() <-- re-connect to existing loader, onCreateLoader() not called
A.onLoadFinished()
A.onStart()
A.onResume()
Run Code Online (Sandbox Code Playgroud)
然后我打开一个子活动B并旋转我的设备.当我完成B并返回活动AI时,请看以下运行:
B.onPause()
A.onLoaderReset() <- why does this run?
A.onDestroy()
A.onCreate()
A.onCreateLoader() <- now runs as loader is null
A.onStart()
...
Run Code Online (Sandbox Code Playgroud)
为什么我的装载机重置,因为我打开了活动B并且设备旋转了?只是添加活动B与DB或CursorLoader无关.