我试图从循环中调用AsyncTask。它工作正常但问题是它需要花费更多的时间来执行所有请求。请告诉我如何才能让它更快。
for (int i = 0; i < 6; i++) {
response = requestWeatherUpdate(location);
}
requestWeatherUpdate
private WeatherResponse requestWeatherUpdate(String location) {
url = ""+ location;
Log.d("URL for Weather Upadate", url);
WeatherUpdateAsyncTask weatherReq = new WeatherUpdateAsyncTask();
String weatherRequestResponse = "";
try {
weatherRequestResponse = weatherReq.execute(url).get();
if (weatherRequestResponse != "") {
parsedWeatherResponse = ParseWeatherResponseXML
.parseMyTripXML(weatherRequestResponse);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return parsedWeatherResponse;
}
二手CallBack
public class WeatherUpdateAsyncTask extends AsyncTask<String, Void, String> {
Context context;
CallBack callBack;
public WeatherUpdateAsyncTask(CallBack callBack) {
this.callBack = callBack;
}
@Override
protected String doInBackground(String... arg0) {
String responseString = "";
HttpClient client = null;
try {
client = new DefaultHttpClient();
HttpGet get = new HttpGet(arg0[0]);
client.getParams().setParameter("http.socket.timeout", 6000);
client.getParams().setParameter("http.connection.timeout", 6000);
HttpResponse responseGet = client.execute(get);
HttpEntity resEntityGet = responseGet.getEntity();
if (resEntityGet != null) {
responseString = EntityUtils.toString(resEntityGet);
Log.i("GET RESPONSE", responseString.trim());
}
} catch (Exception e) {
Log.d("ANDRO_ASYNC_ERROR", "Error is " + e.toString());
}
Log.d("ANDRO_ASYNC_RESPONSE", responseString.trim());
client.getConnectionManager().shutdown();
return responseString.trim();
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
callBack.run(result);
}
}
requestWeatherUpdate
private WeatherResponse requestWeatherUpdate(String location) {
url = ""
+ location;
Log.d("URL for Weather Upadate", url);
WeatherUpdateAsyncTask weatherReq = new WeatherUpdateAsyncTask(new CallBack() {
@Override
public void run(Object result) {
try {
String AppResponse = (String) result;
response = ParseWeatherResponseXML
.parseMyTripXML(AppResponse);
} catch (Exception e) {
Log.e("TAG Exception Occured",
"Exception is " + e.getMessage());
}
}
});
weatherReq.execute(url);
return response;
}
Frm在这里我打电话
for (int i = 0; i < 4; i++) {
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout layout = (RelativeLayout) inflater.inflate(
R.layout.sector_details, depart_arrivals_details, false);
depart_time = (TextView)layout.findViewById(R.id.depart_time);
depart_airport_city = (TextView)layout.findViewById(R.id.depart_airport_city);
temprature = (TextView)layout.findViewById(R.id.temprature);
humidity = (TextView)layout.findViewById(R.id.humidity);
flight_depart_image = (ImageView)layout.findViewById(R.id.flight_depart_image);
depart_time.setText("20:45");
depart_airport_city.setText("Mumbai");
/*
* This part will be updated when we will se the request and get the response
* then we have to set the temp and humidity for each city that we have recived
* */
temprature.setText("");//Here i have set the values from the response i recived from the AsynkTask
humidity.setText("");//Here i have set the values from the response i recived from the AsynkTask
flight_depart_image.setImageResource(R.drawable.f1);
depart_arrivals_details.addView(layout, i);
}
答案 0 :(得分:3)
在get()
上调用AsyncTask
会阻止调用线程。不要那样做。而是将结果传递给onPostExecute()
中的调用者。
从Honeycomb开始,默认实现在串行执行器上顺序执行asynctasks。要并行运行asynctasks,请使用executeOnExecutor(THREAD_POOL_EXECUTOR, ...)
代替execute(...)
。
答案 1 :(得分:2)
您不应该使用get()
。调用get()
不会使调用异步。而是使用execute
weatherRequestResponse = weatherReq.execute(url).get();
get()
public final Result get ()
Added in API level 3
Waits if necessary for the computation to complete, and then retrieves its result.
Returns
The computed result.
Throws
CancellationException If the computation was cancelled.
ExecutionException If the computation threw an exception.
InterruptedException If the current thread was interrupted while waiting.
对于并行执行,请使用executeOnExecutor
weatherReq.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
如果您的asynctask是您的活动类的内部类,您可以在onPostExecute
中更新ui。如果不是,你可以使用接口作为回调。
Retrieving a returned string from AsyncTask in Android
How do I return a boolean from AsyncTask?
从讨论中你得到NUllPointerException @ temprature.setText(parsedWeatherResponse.getTempInC()+(char) 0x00B0);
您尚未初始化parsedWeatherResponse
。你只宣布了它
parsedWeatherResponse = new WeatherResponse();
答案 2 :(得分:1)
使用executeOnExecutor(THREAD_POOL_EXECUTOR,...)并行运行asynctasks。您也可以使用HttpURLConnection代替DefaultHttpClient / HttpGet
答案 3 :(得分:1)
如果您想从UI线程连接网络,那将非常困难。 “应用程序尝试在其主线程上执行网络操作时引发的异常。
仅针对Honeycomb SDK或更高版本的应用程序进行此操作。针对早期SDK版本的应用程序可以在其主要事件循环线程上进行网络连接,但是非常不鼓励这样做。请参阅文档设计响应性。“
如果你想克服这个困难,请遵循以下说明:
解决方案如下。我从另一个答案中找到了它。它对我有用。并将import语句放到你的java文件中。
import android.os.StrictMode;
将以下代码写入onCreate
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}