我有一个应用程序,因为不能在主线程上执行网络操作,所以我正在使用AsyncTask
,那么问题是,一旦我execute()
了AsyncTask
,然后立即finish()
该活动,甚至用户可能会finish()
整个应用程序,那么我想知道的是:
- 只要在应用程序运行时调用了
execute()
,即使应用程序被关闭,AsyncTask
是否始终会完成doInBackground()
和onPostExecute()
?
我有一个应用程序,因为不能在主线程上执行网络操作,所以我正在使用AsyncTask
,那么问题是,一旦我execute()
了AsyncTask
,然后立即finish()
该活动,甚至用户可能会finish()
整个应用程序,那么我想知道的是:
execute()
,即使应用程序被关闭,AsyncTask
是否始终会完成doInBackground()
和onPostExecute()
?你将能够测试这个功能。是的,它有效。如果执行被调用,你会看到Asynctask仍然会执行,除非它对前台或UI相关做了一些事情(可能导致启动器崩溃)。
但是,如果它被系统关闭,它可能会继续执行方法,也可能不会。我已经在这里进行了测试并回答了评论。
回复评论:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Worker().execute();
}
private class Worker extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... arg0) {
Log.i("SomeTag",
"start do in background at " + System.currentTimeMillis());
String data = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(
"https://stackoverflow.com/questions/tagged/android");
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
data = EntityUtils.toString(httpEntity);
Log.i("SomeTag",
"doInBackGround done at " + System.currentTimeMillis());
} catch (Exception e) {
}
return data;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i("SomeTag", System.currentTimeMillis() / 1000L
+ " post execute \n" + result);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i("SomeTag", System.currentTimeMillis() / 1000L + " onDestory()");
}
04-24 21:42:57.981: I/SomeTag(5961): start do in background at 1366854177994
04-24 21:43:00.974: I/SomeTag(5961): 1366854180 onDestory()
04-24 21:43:02.946: I/SomeTag(5961): doInBackGround done at 1366854182946
04-24 21:43:02.946: I/SomeTag(5961): 1366854182 post execute
04-24 21:43:02.946: I/SomeTag(5961): <!DOCTYPE html>
04-24 21:43:02.946: I/SomeTag(5961): <html>
04-24 21:43:02.946: I/SomeTag(5961): <head>
04-24 21:43:02.946: I/SomeTag(5961):
04-24 21:43:02.946: I/SomeTag(5961): <title>Newest 'android' Questions - Stack Overflow</title>
04-24 21:43:02.946: I/SomeTag(5961): <link rel="shortcut icon" href="http://cdn.sstatic.net/stackoverflow/img/favicon.ico">
//....
onPostExecute()
总是在 UI 线程上运行,所以在那种情况下它永远不会被调用。 - ddmpsonDestroy()
之后UI线程仍然可以运行 - 我没有预料到这一点。因此,取消任何UI任务以释放资源可能是一个非常好的主意。 - ddmpsonPostExecute()
是从UI线程调用的,所以如果UI线程不再运行,它将不会继续运行。然而,doInBackground()
是从单独的工作线程运行的,因此它将一直运行直到完成(或者如果JVM进程被操作系统杀死,这也是可能的)。请注意,AsyncTasks仅建议用于较短的UI绑定后台任务,而不是长时间运行的后台工作(几秒钟)。
简而言之,您不能假设它会继续运行,并且绝对不能假设它会发布其进度或调用onPostExecute()
。
doInBackground()
持续更长时间,例如添加Thread.sleep(5000)
,然后尝试各种场景:
onPostExecute()
中崩溃。onPostExecute()
中崩溃。doInBackground()
的AsyncTask。如果您只是使用new Thread(new Runnable(){...
启动线程,则情况也是如此。
cancel
方法。即使你的UI已被销毁,继续进行网络操作也是无用的。但是,当网络操作完成并尝试更新UI时,应用程序会遇到问题。 - minhaz