2010-07-19 7 views
43

Tengo un problema con el siguiente error en Android:CalledFromWrongThreadException: Sólo el hilo original que creó una jerarquía de vistas puede tocar puntos de vista

CalledFromWrongThreadException ;: Sólo el hilo original que creó una jerarquía vista puede tocar sus puntos de vista

Parece que suceda cuando trato de actualizar un Textview en mi actividad, la llamada para actualizar el TextView es de dentro de mi actividad, pero todavía consigo el error anterior.

lo tengo así:

onCreate(): establece los botones y la vista de texto.

onStateChange() - un detector de notificaciones sobre cambios de estado, cuando recibe una notificación si cambia el TextView para decir un texto diferente.

Cuando llego a la notificación de un nuevo texto que tratan de cambiar el modo de Vista de Texto como:

((TextView)findViewById(R.id.title)).setText("Some Text"); 

pero me sale el error anterior.

Al buscar en Google, parece que debo usar un controlador para cambiar el TextView o tal vez usar AsyncTask?

¿Alguien podría explicar cuál sería mejor usar y por qué?

EDIT: Añadido fragmentos de código:


 public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 

      setContentView(R.layout.my); 

      getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_title); 

      ((TextView)findViewById(R.id.time)).setText("Hello Text"); 


      findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() { 
       public void onClick(View v) { 

        Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:")); 
        startActivity(dialIntent); 

         dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD)); 
         dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));  
       } 
     }); 

    } 

//CallBacks from running Service 

private final ICallDialogActivity.Stub iCallDialogActivity = new ICallDialogActivity.Stub(){ 

@Override 
public void onStateChanged(int callState) 
       throws RemoteException {  
      switch(callState){ 
      case GlobalData.CALL_STATUS_IDLE: 

       break; 

      case GlobalData.CALL_STATUS_DISCONNECTING: 
       byeSetup(); 
       break; 
    } 

}; 

public void byeSetup(){ 

      ((TextView)findViewById(R.id.time)).setText("Bye Text"); 

      findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() { 
       public void onClick(View v) { 
        //Void the Button 
       }}); 
} 
+1

¿Estás en una subclase? onStateChange se reemplaza donde? – Pentium10

+0

Hola Pentium10, se invalida mediante una interfaz AIDL y se comunica con un Servicio, el Servicio recibirá una notificación de algún cambio y luego le indicará a la Actividad que actualice su TextView en función de eso. He agregado fragmentos de código para demostrar mejor lo que estoy intentando. El error parece aparecer de forma muy aleatoria y aparece cuando la Actividad está en primer plano y no. –

+1

posible duplicado de [CalledFromWrongThreadException] (http://stackoverflow.com/questions/3413544/calledfromwrongthreadexception) – jww

Respuesta

69

ves como si están en el hilo equivocado. Intente usar un controlador para actualizar la GUI en el hilo correcto. Vea el ejemplo Handling Expensive Operations in the UI Thread de android.com. Básicamente, envolvería byeSetup en un Runnable y lo invocaría con una instancia de Handler.

Handler refresh = new Handler(Looper.getMainLooper()); 
refresh.post(new Runnable() { 
    public void run() 
    { 
     byeSetup(); 
    } 
}); 
+5

Parece que no tengo que matarme. *Uf* –

2

Para otros, simplemente reemplace byeSetup(); con sus declaraciones de código o métodos. byeSetup() es un método de muestra. Espero que ahorrará algo de tu tiempo.

3

Ampliando la respuesta de willcodejavaforfood para mayor claridad & aplicación ...

Tengo que esto funcione y por debajo es cómo lo hice. Estoy ejecutando múltiples subprocesos de procesamiento en un servicio para que otras soluciones que se ejecutan en la actividad no funcionen, como runOnUiThread (nuevo Runnable() {} ...

poner esto en la parte superior de su clase de servicio por lo que es accesible por todas partes en esta clase:

Handler handler; 

poner esto en su método onCreate clase de servicio o algo que se carga en el hilo principal Servicio

handler= new Handler(Looper.getMainLooper()); 

Pon esto dentro de tu hilo adicional al código 'post back' para que se ejecute en la IU o en la IU del servicio (lo que sea que se llame):

handler.post(new Runnable() { 
    public void run() { 
     playNext(); //or whatever method you want to call thats currently not working 
    } 
}); 
0

Otro enfoque, esta vez haciendo uso de android.os.Message

Ha android.os.Handler definido como un campo dentro de su actividad:

private final Handler myTextHandler = new Handler(new Handler.Callback() { 
    @Override 
    public boolean handleMessage(Message stringMessage) { 
     textView.append((String) stringMessage.obj); 
     return true; 
    } 
}); 

luego alimentar desde el otro hilo de esta manera:

Message stringMessage = Message.obtain(myTextHandler); 
stringMessage.obj = "Hello!"; 
stringMessage.sendToTarget(); 
1
     runOnUiThread(new Runnable() { 
          @Override 
          public void run() { 

           // TODO your Code 
           et_Pass.setText(""); 
          } 
         }); 
Cuestiones relacionadas