Asynctask第一次执行 30秒或更长时间。当我进入活动时会发生这种情况。之后,子句调用Asyntask(当我从前一个活动再次进入活动时)只需要4或5秒,我认为这是“可接受的”。
这是我执行AsyncTask
的代码 @Override
public void onLocationChanged(Location location) {
if (location!=null) {
mlastLocation=location;
double latitud=Double.parseDouble(getIntent().getStringExtra("latitud").replace("Latitud:", ""));
double longitud=Double.parseDouble(getIntent().getStringExtra("longitud").replace("Longitud:", ""));
LatLng origen= new LatLng(latitud,longitud);
LatLng destino=new LatLng(mlastLocation.getLatitude(),mlastLocation.getLongitude());
if (mCount==0) {
FillVariablesAsyncTask tareaAsincrona = new FillVariablesAsyncTask();
tareaAsincrona.execute(origen, destino);
mCount++;
}
}
}
这里是AsyncTask的代码,其中onPostExecute更新成员变量并更新UI。
private class FillVariablesAsyncTask extends AsyncTask<LatLng,Void,Document>{
@Override
protected Document doInBackground(LatLng... params) {
md=new GMapV2Direction();
LatLng origen=new LatLng(params[0].latitude,params[0].longitude);
LatLng destino=new LatLng(params[1].latitude,params[1].longitude);
Document doc = md.getDocument(origen, destino, GMapV2Direction.MODE_WALKING);
/*mUbicacionActual = md.getStartAddress(doc);
mDuration=md.getDurationText(doc);
mDistancia=md.getDistanceText(doc);*/
return doc;
}
@Override
protected void onPostExecute(Document doc) {
super.onPostExecute(doc);
mUbicacionActual = md.getStartAddress(doc);
mDuration=md.getDurationText(doc);
mDistancia=md.getDistanceText(doc);
if (mUbicacionActual!=null && mDistancia!=null && mDuration!=null) {
progressBar.setVisibility(View.GONE);
btnIr.setEnabled(true);
tvOrigenLatitud.setText("Latitud:"+String.valueOf(mlastLocation.getLatitude()));
tvOrigenLongitud.setText("Longitud"+String.valueOf(mlastLocation.getLongitude()));
tvDestino.setText("Destino:" + getIntent().getStringExtra("info").replace("Info:", ""));
tvDestinoLatitud.setText("Latitud:" + getIntent().getStringExtra("latitud").replace("Latitud:", ""));
tvDestinoLongitud.setText("Longitud:" + getIntent().getStringExtra("longitud").replace("Longitud:", ""));
tvOrigen.setText("Origen:" + mUbicacionActual);
tvDistancia.setText("Distancia:"+mDistancia);
tvTiempo.setText("Tiempo:" + mDuration);
}
}
}
我已经尝试了 .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR),但应用程序崩溃了。我也尝试过使用处理程序,但是它显示了相同的行为,第一次需要30秒左右,而子结果只需要几个。
编辑以显示我添加日志的点:
if (mCount==0) {
FillVariablesAsyncTask tareaAsincrona = new FillVariablesAsyncTask();
mStart=System.currentTimeMillis();
Log.i("START_BEFORE_EXECUTE", mStart + "");
tareaAsincrona.execute(origen, destino);
long end=System.currentTimeMillis();
Log.i("ELAPSED_EXECUTE", ((end-mStart)/1000) + "");
mCount++;
}
这里:
protected Document doInBackground(LatLng... params) {
long end;
end =System.currentTimeMillis();
Log.i("ELAPSE_PRE_BACKGROUND",((end- mStart)/1000)+"");
md=new GMapV2Direction();
end=System.currentTimeMillis();
Log.i("ELAPSED_POS_GMAPV2DIR",((end- mStart)/1000)+"");
LatLng origen=new LatLng(params[0].latitude,params[0].longitude);
LatLng destino=new LatLng(params[1].latitude,params[1].longitude);
end=System.currentTimeMillis();
Log.i("ELAPSED_PRE_GETDOCUMENT",((end- mStart)/1000)+"");
Document doc = md.getDocument(origen, destino, GMapV2Direction.MODE_WALKING);
end=System.currentTimeMillis();
Log.i("ELAPSED_POS_BACKGROUND",((end- mStart)/1000)+"");
/*mUbicacionActual = md.getStartAddress(doc);
mDuration=md.getDurationText(doc);
mDistancia=md.getDistanceText(doc);*/
return doc;
}
在这里:
long end=System.currentTimeMillis();
Log.i("ELAPSED_onPostExecute",((end-mStart)/1000)+"");
mUbicacionActual = md.getStartAddress(doc);
mDuration=md.getDurationText(doc);
mDistancia=md.getDistanceText(doc);
end=System.currentTimeMillis();
Log.i("ELAPSED_POST_FILLVARS",((end-mStart)/1000)+"");
if (mUbicacionActual!=null && mDistancia!=null && mDuration!=null) {
progressBar.setVisibility(View.GONE);
btnIr.setEnabled(true);
tvOrigenLatitud.setText("Latitud:" + String.valueOf(mlastLocation.getLatitude()));
tvOrigenLongitud.setText("Longitud" + String.valueOf(mlastLocation.getLongitude()));
tvDestino.setText("Destino:" + getIntent().getStringExtra("info").replace("Info:", ""));
tvDestinoLatitud.setText("Latitud:" + getIntent().getStringExtra("latitud").replace("Latitud:", ""));
tvDestinoLongitud.setText("Longitud:" + getIntent().getStringExtra("longitud").replace("Longitud:", ""));
tvOrigen.setText("Origen:" + mUbicacionActual);
tvDistancia.setText("Distancia:"+mDistancia);
tvTiempo.setText("Tiempo:" + mDuration);
end=System.currentTimeMillis();
Log.i("ELAPSED_POS_onPostExecute", ((end - mStart) / 1000) + "");
}
此图像显示日志输出,它显示3但实际上是30或更多。 [IMG] http://i61.tinypic.com/95o1ef.png[/IMG]
答案 0 :(得分:1)
我还不能发表评论所以你去了:在两个给定代码块的每一行上放置断点后,你可以使用IDE的调试器,看看哪条线最能执行。然后发布你的发现。
答案 1 :(得分:1)
时间与AsyncTask
或Thread
或Handler
或Executor
完全无关
问题在于,您使用的图书馆需要花费很长时间才能拨打服务器或处理信息,而且我不相信您可以做很多事情。这只是第一次,因为我猜测库缓存了结果,但它仍然与您使用的线程模型无关。
我的回答主要是你提出了错误的问题。正确的问题是:
不幸的是,回答它的唯一可能方法是分析它的源代码或直接与库开发人员交谈。
修改强>
帮助您衡量执行情况:
public static class TimeMeasure {
private final DecimalFormat format;
private final double start;
private final String tag;
public TimeMeasure(String tag) {
this.format = new DecimalFormat("0.0");
this.start = System.currentTimeMillis();
this.tag = tag;
log("start);
}
public void log(String message) {
double elapsed = ((double) (System.currentTimeMillis() - start)) / 1000.0;
Log.d(tag, format.format(elapsed) + ": " + message);
}
}
然后在doInBackground
protected Document doInBackground(LatLng... params) {
TimeMeasure tm = new TimeMeasure("Carlos");
// execute something:
tm.log("action 1");
// execute next
tm.log("action 2);
// etc...
}
答案 2 :(得分:0)
正如上面的回答所提到的那样,实际上图书馆需要花费太多时间。
前一段时间我遇到过类似的问题,我记得调试后导致问题的原因是距离和持续时间,如果你得到某种地址,也会导致延迟 (例如)获取街道名称,城市名称和国家等。
我没有找到更好的API
或库来处理这个问题,但我所做的是改善用户体验的方法:
从AsyncTask
开始另一个onPostExecute()
,这将获得持续时间和距离。
2-当应用程序获得持续时间和距离时,不要使用进度对话框或进度条阻止用户界面,只需将加载...作为TextView
的默认值,然后当应用会将数据setText
收到实际值。
3 - 在设置重要数据后,稍后对所有数据进行操作。
希望这会有所帮助。