使用AsyncTaskLoader
时我遇到了一些麻烦,屏幕方向也发生了变化。让我给你一些关于我的应用程序结构的背景:我有一个非常简单的应用程序,它从一个URL获取结果并显示它。该应用由一个FragmentActivity
和三个Fragments
组成。我的三个片段如下:
AsyncTaskLoader
用于从内容提供商(如果已缓存)或从网络加载数据。
一切都很有效,直到屏幕显示变化!我查看了LoaderManager.enableDebugLogging(true)
的输出,似乎问题的根源是我的活动中没有调用LoaderCallbacks.onLoadFinished
。
以下是启动加载程序的代码:
/* This function is defined in the "first" fragment in an interface and
* implemented in the activity */
@Override
public void onFormSubmission(String word) {
showLoadingFragment();
if ( mWord == null || mWord.equals(word) ) {
getSupportLoaderManager().initLoader(0, word, this);
} else {
getSupportLoaderManager().restartLoader(0, word, this);
}
// Store the word
mWord = word;
}
显示结果的代码:
@Override
public void onLoadFinished(Loader<Bundle> loader, Bundle data) {
// Validation and other stuff
ResultFragment fragment = new ResultFragment();
// Add the fragment to the 'result_fragment_container' FrameLayout
getSupportFragmentManager()
.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
// Replace loading fragment with the result
.replace(R.id.result_fragment_container, fragment)
.commitAllowingStateLoss();
}
我试过但尝试失败的方法:
setRetaininstance(true)
。android:configChanges="orientation|keyboardHidden|keyboard"
。我没有想法,所以任何帮助都会受到赞赏。
答案 0 :(得分:1)
您应该将getSupportLoaderManager().initLoader(0, null, this);
放入onActivityCreated
方法中。如果加载器已经存在,initLoader将创建或重新连接
答案 1 :(得分:1)
您好我可以提出两种可能的解决方案:
1)从你的问题我不完全确定你的表演在AsyncTask中从不调用OnLoadFinished()。我假设是Async
数据库调用或Web服务器调用等?
无论onLoadFinished()可能都没有被调用,因为你的Activity在旋转时被销毁了。您需要保存在轮换之前更新的状态并调用onDestroy()
您可以尝试保留类变量状态标志。这是在“更新”Async
任务中设置的,该任务标记您的Async
任务是否仍在运行,即“更新”与否。
所以:
bUpdating = true
任务开始时async
。即在内
onPreExecute()
bUpdating = false
完成后。即在内
onPostExecute()
然后当调用onDestroy()
时(在屏幕旋转之前始终调用),您可以检查bUpdating
。 IF
TRUE
然后您可以将屏幕上已保存在Async
任务中的所有详细信息保存到SharePreferences
在onResume()
内检查您的特定SharePreferences
变量,如果它们存在,请再次启动Async
更新。
总之,这将是:
SharedPreferences
之前屏幕轮换 - onDestroy()
- 如果布尔表示异步任务正在运行。onResume()
AFTER 屏幕轮换检查SharedPreferences
并通过Async
保存详细信息。onLoadFinished()
方法。检查屏幕旋转可能还有一种更可靠的方法,我没有做太多。
2)当然另一种选择是在你的特定活动上完全阻止屏幕旋转(因为你真的需要在那个屏幕上旋转吗?)。
我有一个应用程序,它在后台录制视频并上传10秒段。它导致了屏幕旋转和我的异步任务的大头痛,所以我完全阻止了旋转,因为它完全没必要。以下是AndroidManifest.xml文件的代码,用于将屏幕方向锁定为纵向:
<activity
android:name="com.blah.YourActivity"
android:label="Register"
android:screenOrientation="portrait">
</activity>
我希望能帮助你
编辑:此外,可能是更明确的方式来了解屏幕正在旋转:
即这种代码:
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.e(TAG, "ORIENTATION_LANDSCAPE");
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.e(TAG, "ORIENTATION_PORTRAIT");
}
}
取自此post
的示例您可以将SharePreferences
保存放在那里。但onResume()仍将用于从中获取您的详细信息。
还有一个link to SharePreferences
,你没有在
Edit2!:另一件事。我只是重新阅读你的问题,你提到“装载机”由于某种原因,我在脑海里这是保存数据,而不是加载。当你调用onResume()时,你是否尝试过简单地重新调用AsyncTaskLoader()
?如果您没有保存,那么您可以忽略我所说的关于将数据保留到SharePreferences
的所有内容,因为您可以在onResume()(在旋转后运行)再次启动加载异步任务