简体   繁体   中英

Android AsyncTask -

I have a thread which loops and shows a progress dialogue, until everything has finished.

In this thread I'm trying to run a class 'MapInteractor' which draws polygons on to the google map. However I got an error, 'not on the main thread'. So I read up a bit about it, and people seemed to suggest using an AsyncTask. I tried this, however I still get an error. The shortened code is show below, as well as the error. If anyone has any idea as to how to fix this, it would be highly appreciated. I have been tearing my hair out for hours!!

    mapInteractor = new MapInteractor(this);
    fileReader = new FileReader(this);

    try {
        progress = ProgressDialog.show(this, progressText, "Loading..",
            true);


        new Thread(new Runnable() { 
            public void run() { 

                //does stuff

          for (CountryData c : countryData){ 
              try {
                c.setLatAndLong(fileReader.getlatlong(c.getCountryName()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
              mapInteractor.execute(c.getLatAndLong());
          }

          runOnUiThread(new Runnable() {              
          @Override 
          public void run() { 
              progress.dismiss(); 
              } 
          }); 
          }
        }).start(); 


    } catch (Exception e) {
        e.printStackTrace();
    }

    }

My Map interactor class:

    public class MapInteractor extends AsyncTask<double[],Integer,Boolean>{

 // Google Map
    private static GoogleMap googleMap;
    private int j = 1;
    static int count = 0;
    private FragmentActivity fragmentActivity  = null;

    public MapInteractor(FragmentActivity  fragmentActivity) {
      this.fragmentActivity = fragmentActivity;
     }


@Override
protected Boolean doInBackground(double[]... latLongs) {
    boolean complete = false;
    count++;
    System.out.println(count);
    if (googleMap == null) {
        googleMap = ((SupportMapFragment) fragmentActivity.getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
    }

    PolygonOptions polygonOptions = new PolygonOptions(); 
    System.out.println("length of array = " + latLongs[0].length);
    for(int i =0;i < latLongs[0].length-1;i++){         
        if(i == 0){
            polygonOptions.add(new LatLng(latLongs[0][j], latLongs[0][i])); 
        }else{
            try{
                if(((i*2 )+1) <= latLongs.length){
                    polygonOptions.add(new LatLng(latLongs[0][(i*2 )+1], latLongs[0][i*2]));
                }

            }catch(Exception e){
                e.printStackTrace();
            };              
        }     
    }
    if(latLongs.length != 0){
        Polygon polygon = googleMap.addPolygon(polygonOptions.strokeColor(Color.TRANSPARENT).fillColor(Color.RED));
        complete = true;
    }
    return complete;
}

I get the following stack trace:

   04-02 10:48:46.320: E/AndroidRuntime(1704): FATAL EXCEPTION: AsyncTask #1
   04-02 10:48:46.320: E/AndroidRuntime(1704): java.lang.RuntimeException: An error occured while executing doInBackground()
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at android.os.AsyncTask$3.done(AsyncTask.java:200)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at java.util.concurrent.FutureTask.run(FutureTask.java:138)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at java.lang.Thread.run(Thread.java:1019)
   04-02 10:48:46.320: E/AndroidRuntime(1704): Caused by: java.lang.IllegalStateException: Not on the main thread
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at maps.k.o.b(Unknown Source)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at maps.i.g.b(Unknown Source)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at maps.e.al.a(Unknown Source)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at etl.onTransact(SourceFile:152)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at android.os.Binder.transact(Binder.java:279)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.addPolygon(Unknown Source)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at com.google.android.gms.maps.GoogleMap.addPolygon(Unknown Source)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at test.threatlevelsystemproject.MapInteractor.doInBackground(MapInteractor.java:60)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at test.threatlevelsystemproject.MapInteractor.doInBackground(MapInteractor.java:1)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at android.os.AsyncTask$2.call(AsyncTask.java:185)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
   04-02 10:48:46.320: E/AndroidRuntime(1704):  ... 4 more

Thanks.

doInBackground method in AsyncTask class, executes in other thread, and you cant do any UI change in this method, you can do UI changes in onPostExecute method.

PolygonOptions polygonOptions;

@Override
protected void onPreExecute() {
   if (googleMap == null) {
       googleMap = ((SupportMapFragment) fragmentActivity.getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
   }
}

....

 @Override
protected void onPostExecute() {
    Polygon polygon = googleMap.addPolygon(polygonOptions.strokeColor(Color.TRANSPARENT).fillColor(Color.RED));
}

or if you want you can create a handler in your Activity and post runnable in doInBackground , for this one you must declare AsyncTask as inner class of you Activity or fragment

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM