2009-10-08 14 views
5

Un'applicazione che sto attualmente sviluppando è in comunicazione con il server e il processo di comunicazione viene eseguito in una sua thread. Esistono chiamate asincrone, ad esempio login() e onLoginResponse().

login() viene chiamato nell'attività principale e la risposta viene gestita anche nell'attività principale (onLoginResponse()). In onLoginResponse() metodo c'è updateGUIState() metodo che modifica elementi tavola:

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"); 
    } 
} 

Quando l'esecuzione raggiunge questo metodo (quando chiamato da onLoginResponse()) l'applicazione si blocca e il registro visualizza il messaggio seguente:

android.view.ViewRoot $ CalledFromWrongThreadException: solo il thread originale che ha creato una gerarchia di viste può toccare le sue viste.

Qualcuno sa come è possibile modificare la logica per passare al thread appropriato prima di modificare il layout e risolvere il problema?

Grazie!

risposta

17

Prova Handler.

È onLoginResponse() è una funzione di richiamata?
Se lo è, il problema può essere risolto da Handler.

In onLoginResponse(),

hRefresh.sendEmptyMessage(REFRESH); 


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

Vorrei aver trovato questa risposta a lungo, ho avuto lo stesso identico problema e mi ci sono voluti circa una settimana per capire la soluzione, che è esattamente quello che hai menzionato – aryaxt

+0

Ho trovato almeno 5 risposte diverse per questo eccezione. Solo questo ha funzionato per me! –

3

updateGUIState() deve essere eseguito sul thread dell'interfaccia utente. Una possibile soluzione è implementare l'aggiornamento della GUI in un Runnable e chiamare il metodo runOnUiThread con il runnable.

0

Per aggiungere alla risposta di bhatt4982, è anche possibile chiamare handler.post(onLoginThread), dove onLoginThread è un Thread cui eseguibile verrà eseguito all'interno del filo GUI.

Problemi correlati