2010-11-15 16 views
31

tengo el siguiente códigoAsyncTask y Looper.prepare() Error

class OverlayTask extends AsyncTask<Void, Void, Void> { 
    @Override 
    public void onPreExecute() { 

     if (sites != null) { 
      myMapView.getOverlays().remove(sites); 
      myMapView.invalidate(); 
      sites = null; 
     } 
    } 

    @Override 
    public Void doInBackground(Void... unused) { 
      grabShipsWithLocation(); 
      return (null); 
    } 

    @Override 
    public void onPostExecute(Void unused) { 
     myMapView.getOverlays().add(sites); 
     myMapView.invalidate(); 
     isLoading = false; 
    } 
} 

que parece funcionar bien en un par de dispositivos de prueba, pero estoy viendo una gran cantidad de errores que aparecen en la consola prog. Parece que no puedo averiguar por qué y dónde colocar este Looper.prepare(). ¿Es necesario?

java.lang.ExceptionInInitializerError 
at com.test.appname.FinderMain$1.gotLocation(FinderMain.java:286) 
at com.test.appname.MyLocation$GetLastLocation.run(MyLocation.java:89) 
at java.util.Timer$TimerImpl.run(Timer.java:289) 
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
at android.os.Handler.<init>(Handler.java:121) 
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421) 
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421) 
at android.os.AsyncTask.<clinit>(AsyncTask.java:152) 

conforme a lo solicitado MyLocation.java

class GetLastLocation extends TimerTask { 
    @Override 
    public void run() { 
     lm.removeUpdates(locationListenerGps); 
     lm.removeUpdates(locationListenerNetwork); 

     Location net_loc=null, gps_loc=null; 
     if(gps_enabled) 
      gps_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
     if(network_enabled) 
      net_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 

     //if there are both values use the latest one 
     if(gps_loc!=null && net_loc!=null){ 
      if(gps_loc.getTime()>net_loc.getTime()) 
       locationResult.gotLocation(gps_loc); 
      else 
       locationResult.gotLocation(net_loc); 
      return; 
     } 

     if(gps_loc!=null){ 
      locationResult.gotLocation(gps_loc); //Line 89 
      return; 
     } 
     if(net_loc!=null){ 
      locationResult.gotLocation(net_loc); 
      return; 
     } 
     locationResult.gotLocation(null); 
    } 
} 
+1

¿Qué significa grabShipsWithLocation() do? – Falmarri

+1

¿Qué línea es MyLocation.java:89? agrega un comentario a tu fuente – blindstuff

+0

¿Está creando/iniciando AsyncTask desde el hilo principal? – gngr44

Respuesta

95

larga historia:

AsyncTask utiliza internamente una Handler. Un manejador básicamente le permite publicar Runnables desde otro subproceso en el subproceso al que se asignó el controlador, que en el caso de AsyncTask es siempre el subproceso desde el que se llama. Esto solo funciona para hilos que tienen un Looper preparado, sin embargo.

Para obtener más información, véase http://developer.android.com/reference/android/os/Handler.html

historia corta:

Simplemente envuelva cada llamada a FinderMain$1.gotLocation o la creación de AsyncTask dentro de él en un Runnable, y que lo ponga a un Handler unido al hilo de interfaz de usuario , de esta manera:

class GetLastLocation extends TimerTask { 
    private Handler mHandler = new Handler(Looper.getMainLooper()); 

    @Override 
    public void run() { 
     // ... 
     mHandler.post(new Runnable() { 
      public void run() { 
       locationResult.gotLocation(null); 
      } 
     }); 
     // ... 
    } 
} 
+0

Solo el locationResult.gotLocation (null); en la nueva sección o en el lote completo de arriba? –

+0

O cada locationResult.gotLocation (cosas) ?? –

+0

Todas las llamadas a gotLocation deben realizarse dentro del subproceso UI, es decir, en Runnable como se indica anteriormente. También puede envolver toda la sección dentro de ella, pero tenga en cuenta que esto podría ralentizar su UI, si su ejecución lleva demasiado tiempo. Alternativamente, también puede ajustar la creación AsyncTask dentro de gotLocation en un Runnable como este. –

18

yo probamos este ... funcionó, espero que le ayudará a ..

protected class Asyctast extends AsyncTask<String, Integer, Integer> 
{ 

    @Override 
    protected Integer doInBackground(String... params) { 
     // TODO Auto-generated method stub 


     Log.d("Asynctask", ""+params); 
Looper.prepare(); 

     ImageThumbnailsActivity m = new ImageThumbnailsActivity(); 

      Toast.makeText(ImageThumbnailsActivity.this,""+params ,Toast.LENGTH_SHORT).show(); 
      final Dialog dialog_options = new Dialog(ImageThumbnailsActivity.this); 
      dialog_options.setContentView(R.layout.option); 
      dialog_options.show(); 
     Looper.loop(); 
     return null; 
    }  
} 
+7

No es una buena solución, porque Looper.loop() se bloqueará para siempre y el hilo nunca se hará. Deberías usar Looper.myLooper(). Quit() para evitar esto. Excepto por eso, si necesita llamar a Looper.prepare() desde Thread, use Thread en lugar de AsyncTask. – Borg8

+1

Quitar Looper.loop() funcionó para evitar bucle infinito – jgpATs2w