我试图同时运行两个AsyncTasks。(平台为Android 1.5, HTC Hero)
但是,只执行第一个。下面是一个简单的片段来描述我的问题:
public class AndroidJunk extends Activity {
class PrinterTask extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String ... x) {
while (true) {
System.out.println(x[0]);
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new PrinterTask().execute("bar bar bar");
new PrinterTask().execute("foo foo foo");
System.out.println("onCreate() is done.");
}
}
我期望的输出是:
onCreate() is done.
bar bar bar
foo foo foo
bar bar bar
foo foo foo
等等。然而,我得到的是:
onCreate() is done.
bar bar bar
bar bar bar
bar bar bar
第二个AsyncTask永远不会被执行。如果我改变execute()语句的顺序,只有foo任务将产生输出。
我是否遗漏了一些明显的东西,或者做了一些愚蠢的事情?不可能同时运行两个asynctask吗?
编辑:我意识到问题手机运行Android 1.5,我更新了问题描述。相应的行动。运行Android 2.1的HTC Hero就没有这个问题。嗯…
这是可能的。
我的android设备版本是4.0.4和android.os. build . version。SDK_INT是15
我有3个旋转器
Spinner c_fruit=(Spinner) findViewById(R.id.fruits);
Spinner c_vegetable=(Spinner) findViewById(R.id.vegetables);
Spinner c_beverage=(Spinner) findViewById(R.id.beverages);
我还有一个Async-Tack类。
这是我的转轮加载代码
RequestSend reqs_fruit = new RequestSend(this);
reqs_fruit.where="Get_fruit_List";
reqs_fruit.title="Loading fruit";
reqs_fruit.execute();
RequestSend reqs_vegetable = new RequestSend(this);
reqs_vegetable.where="Get_vegetable_List";
reqs_vegetable.title="Loading vegetable";
reqs_vegetable.execute();
RequestSend reqs_beverage = new RequestSend(this);
reqs_beverage.where="Get_beverage_List";
reqs_beverage.title="Loading beverage";
reqs_beverage.execute();
这工作得很完美。我的纺纱机一个接一个装上。我没有使用executeOnExecutor。
这是我的异步任务类
public class RequestSend extends AsyncTask<String, String, String > {
private ProgressDialog dialog = null;
public Spinner spin;
public String where;
public String title;
Context con;
Activity activity;
String[] items;
public RequestSend(Context activityContext) {
con = activityContext;
dialog = new ProgressDialog(activityContext);
this.activity = activityContext;
}
@Override
protected void onPostExecute(String result) {
try {
ArrayAdapter<String> adapter = new ArrayAdapter<String> (activity, android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spin.setAdapter(adapter);
} catch (NullPointerException e) {
Toast.makeText(activity, "Can not load list. Check your connection", Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (Exception e) {
Toast.makeText(activity, "Can not load list. Check your connection", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
super.onPostExecute(result);
if (dialog != null)
dialog.dismiss();
}
protected void onPreExecute() {
super.onPreExecute();
dialog.setTitle(title);
dialog.setMessage("Wait...");
dialog.setCancelable(false);
dialog.show();
}
@Override
protected String doInBackground(String... Strings) {
try {
Send_Request();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void Send_Request() throws JSONException {
try {
String DataSendingTo = "http://www.example.com/AppRequest/" + where;
//HttpClient
HttpClient httpClient = new DefaultHttpClient();
//Post header
HttpPost httpPost = new HttpPost(DataSendingTo);
//Adding data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("authorized","001"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
BufferedReader reader;
try {
reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line) ;
}
JSONTokener tokener = new JSONTokener(builder.toString());
JSONArray finalResult = new JSONArray(tokener);
items = new String[finalResult.length()];
// looping through All details and store in public String array
for(int i = 0; i < finalResult.length(); i++) {
JSONObject c = finalResult.getJSONObject(i);
items[i]=c.getString("data_name");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是可能的。
我的android设备版本是4.0.4和android.os. build . version。SDK_INT是15
我有3个旋转器
Spinner c_fruit=(Spinner) findViewById(R.id.fruits);
Spinner c_vegetable=(Spinner) findViewById(R.id.vegetables);
Spinner c_beverage=(Spinner) findViewById(R.id.beverages);
我还有一个Async-Tack类。
这是我的转轮加载代码
RequestSend reqs_fruit = new RequestSend(this);
reqs_fruit.where="Get_fruit_List";
reqs_fruit.title="Loading fruit";
reqs_fruit.execute();
RequestSend reqs_vegetable = new RequestSend(this);
reqs_vegetable.where="Get_vegetable_List";
reqs_vegetable.title="Loading vegetable";
reqs_vegetable.execute();
RequestSend reqs_beverage = new RequestSend(this);
reqs_beverage.where="Get_beverage_List";
reqs_beverage.title="Loading beverage";
reqs_beverage.execute();
这工作得很完美。我的纺纱机一个接一个装上。我没有使用executeOnExecutor。
这是我的异步任务类
public class RequestSend extends AsyncTask<String, String, String > {
private ProgressDialog dialog = null;
public Spinner spin;
public String where;
public String title;
Context con;
Activity activity;
String[] items;
public RequestSend(Context activityContext) {
con = activityContext;
dialog = new ProgressDialog(activityContext);
this.activity = activityContext;
}
@Override
protected void onPostExecute(String result) {
try {
ArrayAdapter<String> adapter = new ArrayAdapter<String> (activity, android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spin.setAdapter(adapter);
} catch (NullPointerException e) {
Toast.makeText(activity, "Can not load list. Check your connection", Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (Exception e) {
Toast.makeText(activity, "Can not load list. Check your connection", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
super.onPostExecute(result);
if (dialog != null)
dialog.dismiss();
}
protected void onPreExecute() {
super.onPreExecute();
dialog.setTitle(title);
dialog.setMessage("Wait...");
dialog.setCancelable(false);
dialog.show();
}
@Override
protected String doInBackground(String... Strings) {
try {
Send_Request();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void Send_Request() throws JSONException {
try {
String DataSendingTo = "http://www.example.com/AppRequest/" + where;
//HttpClient
HttpClient httpClient = new DefaultHttpClient();
//Post header
HttpPost httpPost = new HttpPost(DataSendingTo);
//Adding data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("authorized","001"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
BufferedReader reader;
try {
reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line) ;
}
JSONTokener tokener = new JSONTokener(builder.toString());
JSONArray finalResult = new JSONArray(tokener);
items = new String[finalResult.length()];
// looping through All details and store in public String array
for(int i = 0; i < finalResult.length(); i++) {
JSONObject c = finalResult.getJSONObject(i);
items[i]=c.getString("data_name");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这允许在API 4+ (android 1.6+)的所有android版本上并行执行:
@TargetApi(Build.VERSION_CODES.HONEYCOMB) // API 11
void startMyTask(AsyncTask asyncTask) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
else
asyncTask.execute(params);
}
这是对Arhimed精彩回答的总结。
Please make sure you use API level 11 or higher as your project build target. In Eclipse, that is Project > Properties > Android > Project Build Target. This will not break backward compatibility to lower API levels. Don't worry, you will get Lint errors if your accidentally use features introduced later than minSdkVersion. If you really want to use features introduced later than minSdkVersion, you can suppress those errors using annotations, but in that case, you need take care about compatibility yourself. This is exactly what happened in the code snippet above.
更新2022
请注意,AsyncTasks在很久以前就被弃用了。如果你使用Kotlin,建议使用Kotlin协程,如果你的项目依赖于使用Java,另一种选择是使用Java .util.concurrent中的executor。(源)