Android: android.view.ViewRoot $ CalledFromWrongThreadException - Как решить проблему? - PullRequest
5 голосов
/ 08 октября 2009

Приложение, которое я сейчас разрабатываю, связывается с сервером, и процесс связи выполняется в своем собственном потоке. Есть асинхронные вызовы - например, login () и onLoginResponse ().

login () вызывается в основной активности, а ответ обрабатывается также в основной активности (onLoginResponse ()). В методе onLoginResponse () есть метод updateGUIState (), который изменяет элементы макета:

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

Когда выполнение достигает этого метода (при вызове из onLoginResponse ()), приложение завершает работу, и в журнале отображается следующее сообщение:

android.view.ViewRoot $ CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может касаться его представлений.

Кто-нибудь знает, как можно изменить логику, чтобы переключиться на соответствующий поток перед изменением макета и устранить проблему?

Спасибо!

Ответы [ 3 ]

17 голосов
/ 08 октября 2009

Попробуйте Handler.

Является ли onLoginResponse() функцией обратного вызова?
Если это так, проблема может быть решена обработчиком.

В onLoginResponse(),

hRefresh.sendEmptyMessage(REFRESH);


    Handler hRefresh = new Handler(){
    @Override
    public void handleMessage(Message msg) {
    switch(msg.what){
         case REFRESH:
                /*Refresh UI*/
                updateGUIState();
                break;
       }
    }
};
3 голосов
/ 08 октября 2009

updateGUIState() необходимо запустить в потоке пользовательского интерфейса. Возможное решение состоит в том, чтобы внедрить обновление GUI в Runnable и вызвать метод runOnUiThread с вашим runnable.

0 голосов
/ 09 октября 2009

Чтобы добавить к ответу bhatt4982, вы также можете вызвать handler.post(onLoginThread), где onLoginThread - это Thread, чей исполняемый файл будет работать внутри потока GUI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...