无法使用AsyncTask

时间:2018-02-24 06:04:02

标签: android user-interface

我的Android应用程序中有MapActivity,我想绘制从源到目的地的路线,然后沿找到的路径绘制polyline。我正在显示progressDialog,同时沿路径绘制polyline

我认为绘制折线是一项繁重的任务,因为它导致progressDialog停止旋转。所以我将drawPolyline功能放在AsyncTask

但我现在面临的问题是我没有更新屏幕,但突然MapActivity屏幕闪烁并消失,我现在看到了MainActivity。

为什么会这样? 我想知道在AsyncTask的背景下更新UI是否在概念上是正确的?如果是,我们该如何去做呢?

注意:我已经通过放置breakPoints来检查AsyncTask功能。它按预期工作但drawPolyline导致错误。 另外drawPolyline没有问题,因为它在没有AsyncTask的情况下调用时工作正常。

这是我的AsyncTask代码:

public class DrawRoute {

    private WeatherMapActivity listener;
    private GoogleMap mMap = WeatherMapActivity.mMap;
    private List<Step> stepsInThePath = WeatherMapActivity.stepsInThePath;

    public DrawRoute(WeatherMapActivity listener) {
        this.listener = listener;
        Log.d("imHere", "in the DrawRouteConstructor");
    }

    public void execute(){
        Log.d("imHere", "in the execute of DrawRoute");
        new DrawPolyline().execute();
    }

    private class DrawPolyline extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            Log.d("imHere", "in the PreExecute");
        }

        @Override
        protected Void doInBackground(Void... voids) {

            Log.d("imHere", "in the Background");
            Geocoder geocoder = new Geocoder(listener, Locale.getDefault());

            mMap.addPolyline(new PolylineOptions()
                    .add(stepsInThePath.get(0).startLocation, stepsInThePath.get(0).endLocation)
                    .width(8)
                    .color(Color.RED));

            mMap.addMarker(new MarkerOptions()
                    .title(MainActivity.sourceAddress)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.start_red))
                    .position(stepsInThePath.get(0).startLocation));

            mMap.addMarker(new MarkerOptions()
                    .title(MainActivity.destinationAddress)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.end_green))
                    .position(stepsInThePath.get(stepsInThePath.size()-1).endLocation));


            for(int i=1; i < stepsInThePath.size(); i++){
                mMap.addPolyline(new PolylineOptions()
                        .add(stepsInThePath.get(i-1).endLocation, stepsInThePath.get(i).endLocation)
                        .width(8)
                        .color(Color.RED));

                List<Address> addresses = null;
                try {
                    addresses = geocoder.getFromLocation(stepsInThePath.get(i).startLocation.latitude, stepsInThePath.get(i).startLocation.longitude, 1);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                String cityName = addresses.get(0).getLocality();

                if(i%5 == 0 || i == stepsInThePath.size()-1){
                    mMap.addMarker(new MarkerOptions()
                            .title(cityName)
                            .position(stepsInThePath.get(i).startLocation));
                }
            }

            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(stepsInThePath.get(0).startLocation, 5));

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            Log.d("imHere", "in the PostExecute");
//            progressDialog.dismiss();
        }
    }
}

任何建议都将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:1)

永远不要尝试直接从doInBackground()方法更新UI元素。 doInBackground()的目的是不通过在单独的线程中运行来从主线程(UI线程)卸载一些工作来阻止UI。 因此,从doInBackground()开始,调用publishProgress()将您的进度传递给onProgressUpdate()函数以执行UI操作。

答案 1 :(得分:0)

doInBackground()的{​​{1}}意味着在后台运行,除了MainThread 之外,没有其他线程可以更新用户界面。

你可以做什么在AsyncTask进行所有计算并将其返回。然后画在doInBackground()。或者您可以使用MainThread处理程序从onPostExecute()进行绘制。

doInBackground()

OR

Handler mainHandler = new Handler(Looper.getMainLooper());