我有一个主要的Activity A,它使用CursorLoader来查询数据库。这是我在活动onCreate()方法中创建的:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
getSupportLoaderManager().initLoader(LOADER_MEASUREMENTS, null, A.this);
}
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)
当我旋转设备时,我看到正确的生命周期方法运行:
A.onPause()
A.onStop()
A.onDestroy()
A.onCreate() <-- re-connect to existing loader, onCreateLoader() not called
A.onLoadFinished()
A.onStart()
A.onResume()
然后我打开一个子活动B并旋转我的设备。当我完成B并返回活动A时,我看到以下运行:
B.onPause()
A.onLoaderReset() <- why does this run?
A.onDestroy()
A.onCreate()
A.onCreateLoader() <- now runs as loader is null
A.onStart()
...
为什么我的装载机会重置,因为我打开了活动B并让设备旋转?只是添加活动B与DB或CursorLoader无关。
答案 0 :(得分:3)
我检查了 LoaderManager source code您将找到此方法:
.outer {
display: table;
position: absolute;
height: 100%;
width: 100%;
}
.middle {
display: table-cell;
vertical-align: middle;
}
.inner {
margin-left: auto;
margin-right: auto;
width: /*whatever width you want*/;
}
在旋转屏幕时(由于配置更改),您的加载程序似乎被破坏了。 LoaderManager 在内部调用 destroyLoader 方法,后者又调用 onLoaderReset 回调方法。
答案 1 :(得分:2)
这似乎与LoaderManager
有关,而不是保留活动状态。
LoaderManager
由android.app.FragmentHostCallback
管理,此类中的void doLoaderStop(boolean retain)
似乎有所不同。根据参数,它将是retain()
或stop()
其加载器。
更改活动A(旋转屏幕)中的配置时,活动会被销毁并立即重新创建。在ActivityThread#handleRelaunchActivity()
中,活动的mChangingConfigurations
值设置为true
。这很重要,因为在配置更改停止活动时,会在Activity
:
final void performStop() {
mDoReportFullyDrawn = false;
mFragments.doLoaderStop(mChangingConfigurations /*retain*/);
// ...
}
你可以尝试深入了解发生的事情 - 你的Android安装应该有源代码,而grep
很棒 - 但我只是总结一下其他内容。
免责声明:我没有彻底核实以下情况,但这是我理解的情况。
如上所示,当看到活动适合重新启动时,它将保留加载器而不是停止它们。旋转活动A时,加载器将被保留。当您旋转活动B时,活动B会立即重新创建,而活动A则会被销毁。与以前相反,装载机将被停止。
LoaderManager可以直接销毁并重新创建已停止的加载器,这就是您所发生的事情。
如果您想自己好好看看,请查看:
app/LoaderManager
或v4/app/LoaderManager
app/FragmentHostCallback
Activity
和ActivityThread
答案 2 :(得分:1)
您可以在A.onLoaderReset()中设置断点并在调试模式下运行应用程序以查看堆栈跟踪,以便使用以下内容进行故障排除:
class A extends Activity implements LoaderManager.LoaderCallbacks
{
@Override
public void onLoaderReset(Loader loader)
{
try
{
// Constructs a new Exception that includes the current stack trace.
throw new Exception();
}
catch (Exception e)
{
Log.d("TAG", Log.getStackTraceString(e));
}
}
}