此问题与需要杀死AsyncTask
的{{1}}有关。当任务正在运行时,活动将被销毁并重新创建(例如,电话轮换)。在ProgressDialog
的帮助下创建了一个新对话框,但由先前销毁的活动产生的onSaveInstanceState()
无法看到它。
图片,如果你愿意...(例如快速模型代码)。
AsyncTask
public class Bob extends Activity {
private ProgressDialog m_d;
public void onCreate(Bundle b) {
m_d = new ProgressDialog(this);
// ...
if (b != null) {
if (b.getBoolean("dialog") == true)
m_d.show();
}
// ...
}
public void onSaveInstanceState(Bundle b) {
super.onSaveInstanceState(b);
b.putBoolean("dialog", (m_d.isShowing()));
}
public void onDestroy() {
if (m_d.isShowing()) {
m_d.dismiss();
m_d = null;
}
//...
}
}
AsyncTask
执行onPreExecute()
而m_d.show()
执行onPostExecute()
。
问题是当我的活动被重新创建时(例如,在电话轮换时),m_d.hide()
似乎有旧的AsyncTask
。它是m_d
,因为它在null
中被杀死。
它没有在重新创建活动时创建的新onDestroy()
。所以现在我有了一个m_d
,那个应该在ProgressDialog
中杀死它的人看不到它。
现在怎样?我需要旧onPostExecute()
以某种方式表示新AsyncTask
消失。
ProgressDialog
如果Android在任务运行时没有杀死我的活动,那很好。 private OnItemSelectedListener onSpinnerSelection = new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// ...
new Switcharoo().execute();
}
}
private class Switcharoo extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
m_d.show();
// ...
}
protected void onPostExecute() {
if (m_d != null) m_d.hide();
// ...
}
protected Void doInBackground(Void... arg0) {
// ...
}
}
像我期望的那样弹出并消失。
如果Android决定在任务运行时因任何原因重新启动我的活动,ProgressDialog
m_d
将null
onPostExecute()
即使我在onCreate()
中重新创建了它 - 它有旧的m_d
,而不是新的。{/ p>
答案 0 :(得分:1)
有两个问题:第一个问题是AsyncTask
绑定到创建它的活动。我的意思是,活动的实例。
如果你希望它在活动轮换之间存活,你必须将它存储在其他地方(例如,检查this)。在任何情况下,您都需要从新活动中引用它(您可以做的另一件事是使用模型片段,即没有设置为setRetainInstance(true)
的UI的片段。)
从新创建的活动中引用异步任务后,没有任何东西阻止您使用异步任务本地m_d
和使用新对话框更新它的setter方法。
另请注意,将弱引用指向活动和对话框本身以便允许垃圾回收是一个好习惯。否则,在执行任务本身结束之前,不会释放对话框(可能还有活动本身)。