旋转后,AsyncTaskLoader不会调用onLoadFinished()

时间:2013-10-23 23:28:36

标签: android android-fragments

在按钮上单击我想从两个XML文件创建一个新的SQLite数据库。使用LoaderManager和AsyncTaskLoader似乎是合适的。

Fragment.onCreate()调用:

setRetainInstance(true);

单击该按钮时,我的Fragment设置一个标志,表示它正在创建数据库,更改布局以显示ProgressBar和取消按钮,并调用:

getLoaderManager().initLoader(0, extra, this);

我的电脑/模拟器上的操作需要12秒。如果我旋转屏幕,加载程序继续调用Fragment的onLoaderProgressUpdate(int)(接口回调方法)并完成数据库的创建。但它从不调用onLoadFinished()方法,我可以在其中重置布局,启用按钮和需要数据库存在的操作栏菜单。

我尝试在Fragment.onCreateView()中执行此操作:

if (mCreatDBInProgress) {
    mBTN_CreateDB.setEnabled(false);
    mDBLayout.setVisibility(View.GONE);
    mProgressBarLayout.setVisibility(View.VISIBLE);
    getLoaderManager().restartLoader(0, null, this);
}

但它调用我的onCreateLoader()方法并从头开始整个事情。这是一个问题,因为我没有调用删除数据库的方法,而是通过确定用于创建数据库的XML文件的过程。 XML文件名是我在Bundle arg。

中传递给该方法的内容

我不明白为什么ProgressBar回调方法继续工作,但是AsyncTaskLoader无法调用onLoadFinished()方法。 LogCat显示它执行了deliverResult()。

我试图让Bundle成为一个成员变量,所以我可以在restartLoader()调用中重用它。它启动另一个asyncTaskLoader,我的ProgressBar来回转换,因为两个线程都试图更新它。最终,它会尝试向第一个线程已添加的数据库添加一行SQLConstraintException。

2 个答案:

答案 0 :(得分:0)

好吧,把我吸引到身边!我提出了另外一个想法,它有效!

不要在轮换后调用restartoader(),只需调用:

getLoaderManager().initLoader(0, mExtra, this);

对于(无论什么)原因,这会导致AsynTaskLoader继续第一个线程(而不是启动另一个线程)并重新链接到我的Fragment以进行onLoadFinished()调用。

所以:

initLoader() - 将加载程序重新连接到Fragment,如果使用相同的参数(int, Bundle, this)调用它。

答案 1 :(得分:0)

我有同样的问题,当旋转屏幕onLoadFinished没有调用。 我已经看到很多答案,但没有真正解决问题。 唯一有用的是简单地在getLoaderManager()方法中添加对onCreate的调用(由于旋转而重新创建活动后再次调用它)。 它确实为我解决了这个问题:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    LoaderManager loaderMngr = getLoaderManager();
    Log.d(LOG_TAG, "" + loaderMngr);

还有一点注意我为什么不在这里放置initLoaderrestartLoader:因为我的案例中的Loader是在另一个事件发生后被触发的,所以这是唯一的解决方法对我来说这个问题。 最初的想法来自here