当使用Android中的保留片段在配置更改期间保存AsyncTask时,我想这是最好的方法,但我对UI线程的消息队列调用顺序产生了一些疑问。
例如:想象一下这个场景:
发生
doInBackground()
onPostExecute()
is AsyncTask onDetach()
is running.doInBackground()onPostExecute()
is called
onDetach()
is calledonAttach()
is那么UI线程消息队列可以是这样的吗:
队列顶部-> onDetach() | onPostExecute() | onAttach()
我知道不能,据我所知,对onPostExecute()
的调用将等待配置更改完成,但这是如何工作的呢?来自活动、片段生命周期的调用是否连续执行?
发布于 2013-12-26 03:06:52
在配置更改期间,不可能在Fragment#onDetach()
和Fragment#onAttach()
之间调用onPostExecute()
。这种说法背后的理由有三个:
doInBackground()
方法返回,AsyncTask
就会通过将一条消息发布到主线程的消息队列来调度要在主线程上调用的onPostExecute()
方法。AsyncTask
的消息将包含调用onPostExecute()
方法的代码。由于主线程按顺序处理其消息队列中的消息,因此不可能同时执行这两个消息,因此永远不能在调用onPostExecute()
和onDetach()
之间调用onDetach()
请阅读我在this thread中对Doug Stevenson的回复,了解更详细的解释(包括证明该主张的源代码的链接)。
发布于 2019-11-22 12:51:51
我编写了一个简单的测试来查看保留的Fragment
中的AsyncTask
的生命周期。它可以确认@Alex Lockwood的答案是真的。因此,可以肯定地说,保留Fragment
中的AsyncTask
是最佳实践。谷歌应该将这种方法写入他们的官方文件中。
public class RecordDataFragment extends Fragment {
public static boolean detach = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Timber.d("retain, onAttach");
detach = false;
}
@Override
public void onDetach() {
super.onDetach();
Timber.d("retain, onDetach");
detach = true;
}
public static class TestTask extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String... username) {
Timber.d("retain, looping.");
while(!detach){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Timber.d("retain, exit looping.");
return null;
}
protected void onPostExecute(Void nothing) {
Timber.d("retain, onPostExecute");
}
}
}
public class RecordFragment extends Fragment {
static boolean called = false;
@Override
public void onResume() {
super.onResume();
Timber.d("retain, onResume");
if(!called) {
new RecordDataFragment.TestTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
called = true;
}
}
}
2019-11-22 12:28:55.503 D/RecordDataFragment: retain, onAttach
2019-11-22 12:32:00.263 D/RecordFragment: retain, onViewStateRestored
2019-11-22 12:32:03.538 D/RecordFragment: retain, onResume
2019-11-22 12:32:03.544 D/RecordDataFragment$TestTask: retain, looping.
2019-11-22 12:32:07.273 D/RecordDataFragment: retain, onDetach
2019-11-22 12:32:07.297 D/RecordDataFragment$TestTask: retain, exit looping.
2019-11-22 12:32:07.403 D/RecordFragment: retain, onDestroy
2019-11-22 12:32:07.566 D/RecordDataFragment: retain, onAttach
2019-11-22 12:32:08.621 D/RecordFragment: retain, onViewStateRestored
2019-11-22 12:32:08.870 D/RecordFragment: retain, onResume
2019-11-22 12:32:09.663 D/RecordDataFragment$TestTask: retain, onPostExecute
https://stackoverflow.com/questions/19964180
复制相似问题