2012-04-03 16 views
12

Estoy tratando de lanzar y alertar al diálogo sobre el subproceso de la interfaz de usuario desde mi hilo de fondo, pero tengo problemas con la ejecución de undeOnUiThread. He intentado FindLocation.this.runOnUiThread y runOnUiThread, pero ambos parecen lanzar el mismo error The method runOnUiThread(new Runnable(){}) is undefined for the type new LocationListener(){} (o ...the type FindLocation). ¿Alguna idea de por qué? Aquí hay un fragmento de mi clase FindLocation.java. Esto es llamado por mi actividad principal.runOnUiThread Indefinido para la clase

public class FindLocation extends Thread { 

public boolean inJurisdiction; 
public boolean AlertNotice = false; 
private LocationManager locManager; 
private LocationListener locListener; 

Context ctx; 
public String userId; 

public FindLocation(Context ctx) { 
    this.ctx = ctx; 
} 

public void start(String userId) { 
     this.userId = userId; 
     super.start(); 

     } 

@Override 
public void run() { 
    Looper.prepare(); 
    final String usr = userId; 

    //get a reference to the LocationManager 
    locManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE); 

    //checked to receive updates from the position 
    locListener = new LocationListener() { 
     public void onLocationChanged(Location loc) { 

      String lat = String.valueOf(loc.getLatitude()); 
      String lon = String.valueOf(loc.getLongitude()); 

      Double latitude = loc.getLatitude(); 
      Double longitude = loc.getLongitude(); 

      if (latitude >= 39.15296 && longitude >= -86.547546 && latitude <= 39.184901 && longitude <= -86.504288 || inJurisdiction != false) { 
       Log.i("Test", "Yes"); 

       inJurisdiction = true; 

       FindLocation.this.runOnUiThread(new Runnable() { ///****error here**** 
        public void run() { 
         AlertDialog.Builder alert = new AlertDialog.Builder(ctx); 
         alert.setTitle("Sent"); 
         alert.setMessage("You will be contacted shortly."); 
         alert.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int which) { 
          } 
         }); 
        } 
       }); 
+0

eso es porque 'runOnUiThread' es de' android.app.Activity', no 'java.lang.Thread' – Vladimir

+0

Shoot. ¿Hay alguna manera de implementar algo similar? – mkyong

+0

@Alex He agregado una respuesta – Vladimir

Respuesta

30

Desde runOnUIThread() es el método de Activity, puede pasar referencia a llamar a la actividad en el constructor.

... 
Context ctx; 
Activity act; 
public String userId; 
... 

public FindLocation(Context ctx, Activity act) { 
    this.ctx = ctx; 
    this.act = act; 
} 

y utilizar runOnUIThread() como

act.runOnUiThread(new Runnable() {...}); 

Sin embargo, creo que es inseguro y que necesita tomar precauciones para asegurarse de que su actividad es todavía allí cuando usted está llamando runOnUiThread

+0

Ok, puedo implementar esto sin errores en eclipse, pero cuando lo ejecuto, obtengo un error NullPointerException en la línea 'act.runOnUiThread (new Runnable() {...});'. ¿Por qué sucedería esto? ¿Podría tener algo que ver con mi looper? – mkyong

+0

intenta averiguar qué es realmente 'nulo', agregando 'Log.d (" Test "+" "+ act);' before 'act.runOnUiThread()' - si no es 'act', entonces el problema está en algún lado dentro de tu 'Runnable' – Vladimir

+0

Acabo de encontrarlo, creo. Cuando comienzo el hilo de mi actividad principal, utilizo esta declaración: 'new FindLocation (getBaseContext(), null) .start (usr_id1);' No estoy seguro de qué pasar en lugar de nulo. ¿Algunas ideas? Intenté 'this' y' MainActivity' pero tampoco funcionó. – mkyong

3

runOnUIThread() es un método que pertenece a Activity .. por lo que no se puede llamar desde un hilo.

Así que en lugar de tomar Contexto instancia de actividad en su constructor y lo llaman usando eso .. algo así como

activity.runOnUIThread(); 
1

encontré una aseado y una forma más modular de hacer esto. Para esto necesita haber definido un Application Context. Una vez que tenga eso, puede llamar al RunOnUIThread desde cualquier biblioteca de clase sin el problema de tener una referencia al Activity.

Desde cualquier lugar dentro de su clase llamada a la librería:

Handler handler = new Handler(Application.Context.MainLooper); 
handler.Post(() => doStuff()); 

Por favor tener en cuenta que esto está escrito en C# como yo uso MonoDroid, pero yo creo que es muy similar a Java. Para saber cómo crear un aspecto Application Context en este thread

13
Another better approach.. 

No hay necesidad de crear constructor para hacer actividad.

Solo encasilla el contexto a la clase de Actividad.

((Activity)context).runOnUiThread(new Runnable() 
    { 
     public void run() 
     { 
      Toast.makeText(context, toast, Toast.LENGTH_SHORT).show(); 
     } 
    }); 
+0

Está lanzando una excepción en mi caso: java.lang.ClassCastException: android.app.ContextImpl no se puede convertir a android.app.Activity –

+0

Encontré esto para la solución de mi problema: http: // stackoverflow.com/a/23324440/2223942. ¿Todavía hay formas de usar su camino con éxito? @Nepster –

1

Usted puede extender su clase para incluir Actividad gusta esta

public class YourClass extends Activity {} 

Esto hará 'runOnUiThread' disponible.

Asimismo, recuerda a importar Actividad

import android.app.Activity; 
Cuestiones relacionadas