如何找出正在运行的 AsyncTask?
在我的一项活动中,我确实有多达六个不同的异步任务,它们可能在不同的事件上运行。所有 AsyncTask 都能优雅地处理方向变化(至少我希望如此)。在 onRetainNonConfigurationInstance() 中,我返回当前运行的 AsyncTask 的 AsyncTask 对象。稍后,在 onCreate() 期间,我需要找出从 getLastNonConfigurationInstance() 返回的 AsyncTask 对象。
我在所有 onPostExecute() 方法中使用 Activity 上下文来获取新活动(如果有新活动)。我在 StackOverflow 上发现了这个概念,并对其进行了一些修改,因为我不喜欢“方向改变时垃圾运行任务”范例。希望这个概念是正确的。
在下面显示的代码中,您将发现两个不同的 AsyncTasks。在 onRetainNonConfigurationInstance() 期间,我将返回当前正在运行的 AsyncTask。我的问题出在 onCreate() 内。如何找出返回的对象是什么?当方向改变发生时,什么 AsyncTask 正在运行?
两个 AsyncTasks 在许多方面都不同(此处未显示),因此我没有使用自己的扩展 AsyncTask 基础对象。
非常感谢。
public class MyActivity extends ListActivity {
// First AsyncTask
private class MyLoadAsyncTask extends AsyncTask<Void, Void, Cursor> {
private MyActivity context;
private MyProgressDialog dialog;
public MyLoadAsyncTask(MyActivity context) {
super();
this.context = context;
}
@Override
protected Cursor doInBackground(Void... voids) {
return MyApplication.getSqliteOpenHelper().fetchSoomething();
}
@Override
protected void onPostExecute(Cursor cursor) {
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
if (cursor != null) {
context.startManagingCursor(cursor);
context.adapter = new InternetradiosAdapter(context,
R.layout.row,
cursor,
new String[] { "text1",
"text2" },
new int[] { R.id.row_text1,
R.id.row_text2 } );
if (context.adapter != null) {
context.setListAdapter(context.adapter);
}
}
context.loadTask = null;
}
@Override
protected void onPreExecute () {
dialog = MyProgressDialog.show(context, null, null, true, false);
}
}
private class MyDeleteAsyncTask extends AsyncTask<Void, Void, Boolean> {
// Second AsyncTask
private MyActivity context;
private MyProgressDialog dialog;
private long id;
public MyDeleteAsyncTask(MyActivity context, long id) {
super();
this.context = context;
this.id = id;
}
@Override
protected Boolean doInBackground(Void... voids) {
return MyApplication.getSqliteOpenHelper().deleteSomething(id);
}
@Override
protected void onPostExecute(Boolean result) {
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
if (result) {
context.doRefresh();
}
context.deleteTask = null;
}
@Override
protected void onPreExecute () {
dialog = MyProgressDialog.show(context, null, null, true, false);
}
}
private MyDeleteAsyncTask deleteTask;
private MyLoadAsyncTask loadTask;
@Override
public void onCreate(Bundle bundle) {
// ...
// What Task is returned by getLastNonConfigurationInstance()?
// ...
// xxxTask = (MyXxxAsyncTask) getLastNonConfigurationInstance();
// ...
if (deleteTask != null) {
deleteTask.context = this;
deleteTask.dialog = MyProgressDialog.show(this, null, null, true, false);
} else if (loadTask != null) {
loadTask.context = this;
loadTask.dialog = MyProgressDialog.show(this, null, null, true, false);
} else {
loadTask = new MyLoadAsyncTask(this);
loadTask.execute();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
if (deleteTask != null) {
if (deleteTask.dialog != null) {
deleteTask.dialog.dismiss();
deleteTask.dialog = null;
return deleteTask;
}
} else if (loadTask != null) {
if (loadTask.dialog != null) {
loadTask.dialog.dismiss();
loadTask.dialog = null;
return loadTask;
}
return null;
}
}
In one of my Activities I do have up to six different AsyncTasks that may run on different events. All AsyncTasks handle orientation changes gracefully (at least I hope so). In onRetainNonConfigurationInstance() I do return the AsyncTask object of a currently running AsyncTask. Later, during onCreate(), I need to find out what AsyncTask object is returned from getLastNonConfigurationInstance().
I use the Activity context in all onPostExecute() methods to get the new activity (if there is a new one). I found this concept here on StackOverflow and did modify it a little bit because I don't like that "Trash running tasks on orientation change" paradigma. Hope this concept is correct.
In the code shown below you'll find two different AsyncTasks. During onRetainNonConfigurationInstance() I will return the currently running AsyncTask. My problem is within onCreate(). How to find out what object is returned? What AsyncTask was running when orientation change bumped in?
Both AsyncTasks are different in many areas (not shown here) so I didn't use an own extended AsyncTask base object.
Many thanks in advance.
public class MyActivity extends ListActivity {
// First AsyncTask
private class MyLoadAsyncTask extends AsyncTask<Void, Void, Cursor> {
private MyActivity context;
private MyProgressDialog dialog;
public MyLoadAsyncTask(MyActivity context) {
super();
this.context = context;
}
@Override
protected Cursor doInBackground(Void... voids) {
return MyApplication.getSqliteOpenHelper().fetchSoomething();
}
@Override
protected void onPostExecute(Cursor cursor) {
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
if (cursor != null) {
context.startManagingCursor(cursor);
context.adapter = new InternetradiosAdapter(context,
R.layout.row,
cursor,
new String[] { "text1",
"text2" },
new int[] { R.id.row_text1,
R.id.row_text2 } );
if (context.adapter != null) {
context.setListAdapter(context.adapter);
}
}
context.loadTask = null;
}
@Override
protected void onPreExecute () {
dialog = MyProgressDialog.show(context, null, null, true, false);
}
}
private class MyDeleteAsyncTask extends AsyncTask<Void, Void, Boolean> {
// Second AsyncTask
private MyActivity context;
private MyProgressDialog dialog;
private long id;
public MyDeleteAsyncTask(MyActivity context, long id) {
super();
this.context = context;
this.id = id;
}
@Override
protected Boolean doInBackground(Void... voids) {
return MyApplication.getSqliteOpenHelper().deleteSomething(id);
}
@Override
protected void onPostExecute(Boolean result) {
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
if (result) {
context.doRefresh();
}
context.deleteTask = null;
}
@Override
protected void onPreExecute () {
dialog = MyProgressDialog.show(context, null, null, true, false);
}
}
private MyDeleteAsyncTask deleteTask;
private MyLoadAsyncTask loadTask;
@Override
public void onCreate(Bundle bundle) {
// ...
// What Task is returned by getLastNonConfigurationInstance()?
// ...
// xxxTask = (MyXxxAsyncTask) getLastNonConfigurationInstance();
// ...
if (deleteTask != null) {
deleteTask.context = this;
deleteTask.dialog = MyProgressDialog.show(this, null, null, true, false);
} else if (loadTask != null) {
loadTask.context = this;
loadTask.dialog = MyProgressDialog.show(this, null, null, true, false);
} else {
loadTask = new MyLoadAsyncTask(this);
loadTask.execute();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
if (deleteTask != null) {
if (deleteTask.dialog != null) {
deleteTask.dialog.dismiss();
deleteTask.dialog = null;
return deleteTask;
}
} else if (loadTask != null) {
if (loadTask.dialog != null) {
loadTask.dialog.dismiss();
loadTask.dialog = null;
return loadTask;
}
return null;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在你的 onCreate() 添加:
In your onCreate() add:
我发现处理内部有多个正在运行的 AsyncTasks 的活动的最佳方法是实际返回一个包含所有正在运行的 AsyncTasks 的对象,并在 onCreate() 中自动重新初始化其所有上下文。 >。例如
,现在您只需要在任务开始/完成时添加和删除任务。
I've found that the best way to deal with activities that have multiple running AsyncTasks inside of them is to actually return an object that contains all of the running ones and automatically reinitialize all of their contexts in
onCreate()
. E.g.Now you just need to add and remove the tasks when they start/finish.