2009-07-21 19 views
29

Tengo una actividad llamada A, y en la selección del elemento de menú 0, genera el servicio B, que inicia una C ejecutable en una nueva conversación. Tengo un TextView en la actividad A, que quiero acceder en hilo de C.Cómo acceder a las vistas de la actividad original desde el servicio de fondo generado

He intentado hacer el TextView un campo estático público, pero que genera el siguiente error:

07-21 07:26:25.723: ERROR/AndroidRuntime(1975): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.ViewRoot.checkThread(ViewRoot.java:2440) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.ViewRoot.invalidateChild(ViewRoot.java:522) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:540) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.ViewGroup.invalidateChild(ViewGroup.java:2332) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.View.invalidate(View.java:4437) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView.updateAfterEdit(TextView.java:4593) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView.handleTextChanged(TextView.java:5932) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:6081) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.sendTextChange(SpannableStringBuilder.java:889) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:352) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:269) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:432) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:259) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:28) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView.append(TextView.java:2191) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView.append(TextView.java:2178) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at com.android.peekaboo.DoScan$scanBody.run(DoScan.java:36) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at java.lang.Thread.run(Thread.java:1058) 

también tengo considerado intentar pasar la Vista a través de un intento, pero no sé cómo funcionaría eso. ¿Qué necesito para que esto funcione?

Respuesta

21

Debe actualizar los widgets desde el hilo de la GUI, también conocido como 'el hilo que creó la jerarquía de vista'. La forma estándar de hacerlo es a través de Handler sy se puede encontrar un ejemplo de cómo usar los controladores en ProgressDialog Example (expanda 'Ejemplo de diálogo de progreso con un segundo hilo').

1

La otra forma es utilizar os.android.AsyncTask para el procesamiento.

2

Realmente no desea manipular widgets directamente desde un servicio.

Por ejemplo, supongamos que el usuario desliza el teclado de su G1. Tu actividad es destruida y recreada. Su servicio, sin embargo, se mantiene en widgets de una actividad ahora difunta. En el mejor de los casos, las actualizaciones no ocurrirán. En el peor de los casos, las actualizaciones causarán un bloqueo, o su aplicación perderá memoria porque la actividad anterior no se puede recolectar basura, porque su servicio aún se mantiene.

Tener actividades de notificación de servicios es correcto, siempre que tenga un aislamiento decente entre ellos y la actividad se separe del servicio cuando se destruya.

25

Estaba teniendo un problema similar cuando se necesitaba un ListView para actualizarse en la respuesta del servicio web proveniente de un hilo separado.

Después de analizar un similar question & example, aquí es una solución que debería funcionar para usted:

public class A extends Activity implements Callback { 

    callserviceB() { } // where your service B being called; 

    @Override 
    public void returnServiceResponse() { 
      workOnResponse(); 
      handler.sendEmptyMessage(0); 
    } 

    private Handler handler = new Handler() { 
      public void handleMessage(Message msg) { 
       //update your view from here only. 
      } 
    } 
} 

public class B implements Runnable { 
    Callback callback; 

    public void run() { 
     //your business logic. 
     callback.returnServiceResponse(); 
    } 
} 

public interface Callback { 
    public void returnServiceResponse(); 
} 
+2

ejemplos de código son siempre mucho más útil que las descripciones. Gracias :) – HXCaine

+0

¡Gracias, este problema me ha estado siguiendo durante mucho tiempo! ¡Gracias! – Daniel

Cuestiones relacionadas