2009-10-08 16 views
5

Aplikacja, którą właśnie rozwijam, komunikuje się z serwerem, a proces komunikacji przebiega we własnym wątku. Są wywołania asynchroniczne - na przykład login() i onLoginResponse().

Funkcja login() jest wywoływana w głównej aktywności, a odpowiedź jest obsługiwana również w działaniu głównym (onLoginResponse()). W metodzie onLoginResponse() istnieje updateGUIState() metoda, która modyfikuje elementy układu:

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

Gdy wykonanie osiągnie ten sposób (po nazwie od onLoginResponse()) awarii aplikacji i dziennik wyświetla się następujący komunikat:

android.view.ViewRoot $ CalledFromWrongThreadException: Tylko oryginalny wątek, który utworzył hierarchię widoku, może dotykać swoich widoków.

Czy ktoś wie, jak można zmienić logikę, aby przełączyć się na odpowiedni wątek przed zmodyfikowaniem układu i naprawieniem problemu?

Dzięki!

Odpowiedz

17

Wypróbuj Handler.

Czy onLoginResponse() jest funkcją zwrotną?
Jeśli tak, problem można rozwiązać za pomocą programu Handler.

W onLoginResponse(),

hRefresh.sendEmptyMessage(REFRESH); 


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

Chciałbym znaleźć tę odpowiedź przez długi czas, miałem dokładnie ten sam problem i zajęło mi około tygodnia, aby znaleźć rozwiązanie, które jest dokładnie tym, co wspomniałeś – aryaxt

+0

Znalazłem co najmniej 5 różnych odpowiedzi dla tego wyjątek. Tylko ten pracował dla mnie! –

3

updateGUIState() należy uruchomić na wątku interfejsu użytkownika. Możliwym rozwiązaniem jest zaimplementowanie aktualizacji GUI w Runnable i wywołanie metody runOnUiThread przy użyciu funkcji Runnable.

0

Aby dodać do odpowiedzi bhatt4982, można również zadzwonić handler.post(onLoginThread), gdzie onLoginThread jest Thread którego runnable będzie działać wewnątrz wątku GUI.

Powiązane problemy