2009-10-08 45 views
5

Una aplicación que estoy desarrollando actualmente se está comunicando con el servidor y el proceso de comunicación se ejecuta en su propio hilo. Hay llamadas asincrónicas, por ejemplo, login() y onLoginResponse().

Se llama a login() en la actividad principal y la respuesta se maneja también en la actividad principal (onLoginResponse()). En onLoginResponse() método no es el método updateGUIState() que modifica elementos de Presentación:

private void updateGUIState() { 

    Log.i(TAG, "executing updateGUIState"); 

    arrangeLayoutElements(); 
    txtTime.setText(mStrRecordingTime); 
    if (settings.isRecording()) { 
     //btnAction.setText("Stop"); 
     btnAction.setImageResource(R.drawable.button_stop); 
    } else { 
     //btnAction.setText("Capture"); 
     btnAction.setImageResource(R.drawable.button_record); 
    } 

    //set privacy level text 
    if (settings.getPrivacyLevel() == 0) { 
     txtPrivacyLevel.setText("Private"); 
    } else if (settings.getPrivacyLevel() == 1) { 
     txtPrivacyLevel.setText("Public"); 
    } 

    if (settings.isMute()) { 
     muteIcon.setIconImage(R.drawable.ic_volume_off_small); 
    } else { 
     muteIcon.setIconImage(R.drawable.ic_volume_small); 
    } 

    if (mIsUploading) { 
     txtUploadingText.setVisibility(View.VISIBLE); 
     uploadingProgressBar.setVisibility(View.VISIBLE); 
    } else { 
     txtUploadingText.setVisibility(View.INVISIBLE); 
     uploadingProgressBar.setVisibility(View.INVISIBLE); 
    } 

    if (mEncoderConnection != null) { 
     txtConnectionStatus.setText("Connected"); 
    } else { 
     txtConnectionStatus.setText("Disconnected"); 
    } 
} 

Cuando la ejecución alcanza este método (cuando se llama desde onLoginResponse()) la aplicación se bloquea y el registro muestra el siguiente mensaje:

android.view.ViewRoot $ CalledFromWrongThreadException: Solo el hilo original que creó una jerarquía de vista puede tocar sus vistas.

¿Alguien sabe cómo es posible modificar la lógica para cambiar al hilo apropiado antes de modificar el diseño y solucionar el problema?

Gracias!

Respuesta

17

Probar Handler.

¿onLoginResponse() es una función de devolución de llamada?
Si es así, el problema puede ser resuelto por Handler.

En onLoginResponse(),

hRefresh.sendEmptyMessage(REFRESH); 


    Handler hRefresh = new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 
    switch(msg.what){ 
     case REFRESH: 
       /*Refresh UI*/ 
       updateGUIState(); 
       break; 
     } 
    } 
}; 
+0

Ojalá encontrara esta respuesta hace mucho tiempo, tuve exactamente el mismo problema y tardé aproximadamente una semana en encontrar la solución, que es exactamente lo que mencionó – aryaxt

+0

Encontré al menos 5 respuestas diferentes para esto excepción. ¡Solo este funcionó para mí! –

3

updateGUIState() debe ejecutarse en el subproceso de interfaz de usuario. Una posible solución es implementar su actualización de la GUI en un Runnable, y llame al método runOnUiThread con su ejecutable.

0

Para añadir a la respuesta de bhatt4982, también puede llamar a handler.post(onLoginThread), donde onLoginThread es una Thread cuyo ejecutable se ejecutará dentro del hilo de interfaz gráfica de usuario.

Cuestiones relacionadas