在按钮上单击我想从两个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。
答案 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);
还有一点注意我为什么不在这里放置initLoader
或restartLoader
:因为我的案例中的Loader是在另一个事件发生后被触发的,所以这是唯一的解决方法对我来说这个问题。
最初的想法来自here。