如果我没有误会,以下应该是相同的 使用 AsyncTask :
private class GetDataTask extends AsyncTask<String, Void, String>{
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(String... params) {
return NetConnection.getRecordData(mUserId, mUserPassword);
}
@Override
protected void onPostExecute(String result) {
parseJson(result);
}
}
使用主题:
new Thread( new Runnable() {
@Override
public void run() {
String res = NetConnection. getRecordData(mUserId, mUserPassword);
parseJson(res);
}
}).start();
但是在上传文件时,AsyncTask运行synchronously
,而线程运行asynchronously
(并行)。
为什么会这样?为什么AsyncTask的行为如下? AsyncTask不应该异步运行吗?
我有点困惑,所以我需要你的帮助
这就是我调用GetDataTask的方法:
new GetDataTask().execute()
我更喜欢使用AsyncTask,但它不适合我。有关详细信息,请参阅我的early question
答案 0 :(得分:11)
从4.x调用2个AsyncTasks将导致它们被串行执行。
解决此问题的一种方法是使用以下代码
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
myTask.execute();
}
您可以在以下网址了解详情:http://commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.html
答案 1 :(得分:3)
以下是official java doc ...
的说明执行顺序
首次引入时,AsyncTasks在单个上串行执行 背景线程。从DONUT开始,这被更改为一个池 允许多个任务并行运行的线程。从...开始 HONEYCOMB,任务在单个线程上执行以避免常见 并行执行导致的应用程序错误。
If you truly want parallel execution, you can invoke
executeOnExecutor(java.util.concurrent.Executor, Object[])与THREAD_POOL_EXECUTOR。
所以如果你一起调用两个AsyncTask ......它们不会并行执行(例外是donut,encliar和gingerbread)......你可以使用executeOnExecutor
在parallel
中执行它们。
答案 2 :(得分:2)
从您的代码中我们可以看到您在AsyncTask的parseJson(result);
中调用了onPostExecute()
,它在应用程序的 MainUIThread 中运行。所以在那时你的代码同步运行..
将parseJson(result);
方法放在doInBackGround()
中,该方法仅在其他工作线程中运行。
虽然您在Thread
中调用了相同的内容。所以两者
String res = NetConnection. getRecordData(mUserId, mUserPassword);
parseJson(res);
在异步经历的 MAinUiThread 中运行其他工作线程。
注意:
但请确保parseJson(res);
在doInBackground(
}内时不会更新用户界面。
答案 3 :(得分:0)
看起来实际问题不在文件上传中,而是在parseJson
方法中。
在Thread
示例中,您在单独的线程中解析Json,而在AsyncTask
情况下,您在UI线程中解析Json。