segundo - manual de programacion android pdf
Cómo acceder a las vistas de la actividad original desde el servicio en segundo plano generado (4)
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
y se puede encontrar un ejemplo de cómo usar los manejadores en el ejemplo de ProgressDialog (expanda ''Ejemplo de diálogo de progreso con un segundo hilo'').
Tengo una actividad llamada A, y en la selección del elemento 0 del menú, genera el servicio B, que inicia una C ejecutable en una nueva cadena. Tengo un TextView en la actividad A, al que quiero acceder en el hilo C.
Intenté hacer del TextView un campo público estático, pero eso 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 he considerado tratar de pasar la Vista a través de un intento, pero no sé cómo funcionaría. ¿Qué necesito para que esto funcione?
Estaba teniendo un problema similar donde se requería que ListView se actualizara en la respuesta del servicio web proveniente de un hilo separado.
Después de analizar una pregunta similar y un example , aquí hay 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();
}
La otra forma es utilizar os.android.AsyncTask para el procesamiento.
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 servicios para notificar actividades está bien, siempre y cuando tengas un aislamiento decente entre ellos y la actividad se separe del servicio cuando se destruya.