AsyncTask在第一次执行时花费了太多时间

时间:2015-08-11 11:35:39

标签: android android-asynctask

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]

3 个答案:

答案 0 :(得分:1)

我还不能发表评论所以你去了:在两个给定代码块的每一行上放置断点后,你可以使用IDE的调试器,看看哪条线最能执行。然后发布你的发现。

答案 1 :(得分:1)

时间与AsyncTaskThreadHandlerExecutor完全无关

问题在于,您使用的图书馆需要花费很长时间才能拨打服务器或处理信息,而且我不相信您可以做很多事情。这只是第一次,因为我猜测库缓存了结果,但它仍然与您使用的线程模型无关。

我的回答主要是你提出了错误的问题。正确的问题是:

  • 为什么这个图书馆需要很长时间才能处理,你可以做些什么来缩短它?

不幸的是,回答它的唯一可能方法是分析它的源代码或直接与库开发人员交谈。

修改

帮助您衡量执行情况:

   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 - 在设置重要数据后,稍后对所有数据进行操作。

希望这会有所帮助。