Android AsyncTask第一次执行时花费的时间太长
Asynctask第一次执行需要30秒或更长时间。它发生在我进入活动时。之后,后续调用的异步任务(当我从先前的活动再次进入活动)只花费4或5秒,我认为是“可接受的”。p> 下面是我执行AsyncTask的代码Android AsyncTask第一次执行时花费的时间太长,android,android-asynctask,Android,Android Asynctask,Asynctask第一次执行需要30秒或更长时间。它发生在我进入活动时。之后,后续调用的异步任务(当我从先前的活动再次进入活动)只花费4或5秒,我认为是“可接受的”。p> 下面是我执行AsyncTask的代码 @Override public void onLocationChanged(Location location) { if (location!=null) { mlastLocation=location;
@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);
}
}
}
在这里:
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]我还不能发表评论,所以你可以这样做:在两个给定代码块的每一行上放置断点后,你可以使用IDE的调试器来查看哪一行执行的时间最长。然后发布您的发现。所花的时间与
异步任务
或线程
或处理程序
或执行器
问题是,您正在使用的库调用服务器或处理信息确实需要那么长的时间,我认为您对此无能为力。这只是第一次,因为我猜库会缓存结果,但它仍然与您使用的线程模型无关
我回答的要点是你问错了问题。正确的问题是:
- 为什么这个库需要这么长的时间来处理,您可以做些什么来缩短它
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...
}
正如上面的回答所提到的,实际上是图书馆花费了太多的时间 不久前我遇到了一个类似的问题,我记得在调试后导致问题的原因是距离和持续时间,而且如果您得到某种地址,这将导致延迟 (例如)获取街道名称、城市名称和国家等 我没有找到更好的
API
或库来处理这个问题,但我所做的是改善用户体验:
1-从onPostExecute()
启动另一个AsyncTask
,该任务将获得持续时间和距离
2-当应用程序获得持续时间和距离时,不要用进度对话框或进度条阻塞用户界面,只需将加载。。。作为TextView
的默认值,然后当应用程序收到数据时,将setText
设置为实际值
3-在设置重要数据后,稍后进行所有数据操作
希望这会有所帮助。异步任务实际启动前需要30秒,还是持续
doInBackground()
30秒?事实上,我怀疑第一种情况正在发生……哪一行花了最多的时间?如果你告诉我怎么做,我不知道如何跟踪应用程序。我只知道UI需要大量更新。您可以使用Log
类,并在IDE的LogCat中查看打印的日志:@Carlos Hernández use System.currentTimeMillis();跟踪doInbackground中的时间需要花费时间。此外,我们不应该在asynctask中执行长时间运行的任务这不是asynctask的目的,如果doInbackground中的超时时间太长,请使用IntentService。我用日志更新了我的问题。我在GitHub上有代码,以防有人想测试它。类为GMapV2Direction的行似乎执行得很快。或者你指的是什么库?我猜要么是构造函数(newgmapv2direction()
)要么是方法getDocument(…)
。但我从命令中看到,您也遇到了问题,无法正确地度量这些执行。也许首先要解决这些问题,然后你可以确定是什么花了那么长时间。是的,我在衡量执行情况时遇到了问题,结果似乎不一致。我添加了一些代码来帮助你衡量执行情况。除非你准确地知道哪个电话花了那么长的时间,否则你将无法适当地缩小问题的范围。谢谢你的课,这里有我的结果:谢谢你的回答。持续时间和距离与onPostExecuted中的地址一起使用getDurationText和getDistanceText方法计算得非常快,因此,如果我对您有很好的了解,我认为不需要在那里执行另一个异步任务。正如你所说,问题在于图书馆。我将尝试使用json和另一个http客户端编写它。
protected Document doInBackground(LatLng... params) {
TimeMeasure tm = new TimeMeasure("Carlos");
// execute something:
tm.log("action 1");
// execute next
tm.log("action 2);
// etc...
}