Android:android.view.ViewRoot $ CalledFromWrongThreadException - 如何解决问题?

时间:2009-10-08 09:26:00

标签: android layout multithreading

我正在开发的应用程序正在与服务器通信,并且通信进程在其自己的线程中运行。有异步调用 - 例如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 个答案:

答案 0 :(得分:17)

尝试Handler

onLoginResponse()是否是回调函数?
如果是,问题可以由Handler解决。

onLoginResponse()

hRefresh.sendEmptyMessage(REFRESH);


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

答案 1 :(得分:3)

updateGUIState()需要在UI线程上运行。一种可能的解决方案是在Runnable中实现GUI更新,并使用您的runnable调用runOnUiThread方法。

答案 2 :(得分:0)

要添加到bhatt4982的响应,您还可以调用handler.post(onLoginThread),其中onLoginThreadThread,其runnable将在GUI线程内运行。