为什么我的HandlerThread会更新用户界面

时间:2016-11-10 16:16:40

标签: android multithreading

我目前正在使用简单的相机示例在Android中练习HandlerThread - 问题是如果我在CameraController中创建我的onCreate对象并向处理程序线程发送消息以便处理我的openCamera()方法(包含直接UI更新代码)

它允许我更新UI,虽然我不应该被允许这样做 - 因为技术上我应该在不同的线程中。

如果我移动代码onCheckedChanged方法(在下面的代码段中注释),应用程序将崩溃,说我正在尝试从其他线程更新UI线程。

public class MainActivity extends AppCompatActivity implements Handler.Callback {

private ToggleButton toggleButton;
private TextView textView;
private CameraController mTestCam;

//generate messages
private static final int MSG_OPEN_CAM = 0;
private static final int MSG_CLOSE_CAM = 1;
private static final int MSG_OPEN_FLASH= 2;
private static final int MSG_CLOSE_FLASH = 3;
//verify
private static final int MSG_OPEN_CAM_DONE = 4; // nu trebuie
private static final int MSG_CLOSE_CAM_DONE = 5;
private static final int MSG_OPEN_FLASH_DONE= 6;
private static final int MSG_CLOSE_FLASH_DONE= 7;

//used for MainActivity HandleMessage
protected Handler mHandler;

//camera controler thread
private CameraControllerThread mCameraControlThread;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    //android marshmallow - in order for service to run you need runtime permissions
    //testCam.openCamera(); //moved to method

    toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
    textView = (TextView) findViewById(R.id.textView_text);

    mHandler = new Handler(this);
    mCameraControlThread = new CameraControllerThread("Camera Control Thread");
    mCameraControlThread.start();

    //moved to onStart
    mTestCam = new CameraController();
    Message openCameraMsg = mCameraControlThread.mWorkerHandler.obtainMessage(this.MSG_OPEN_CAM);
    openCameraMsg.sendToTarget();


    toggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {

            if(isChecked){

                mTestCam = new CameraController();
                Message openCameraMsg = mCameraControlThread.mWorkerHandler
                        .obtainMessage(MSG_OPEN_CAM);
                openCameraMsg.sendToTarget();

                //mTestCam.openFlash();
            } else {
                //close flash
                //mTestCam.stopFlash();
            }

        }
    });

}

private void openCamera(){
    synchronized (mTestCam){
        mTestCam.openCamera();
    }
    Toast.makeText(this, "This is my text", Toast.LENGTH_LONG).show();
    textView.setVisibility(View.VISIBLE);
    textView.setText("Camera Open");
}

@Override
public boolean handleMessage(Message message) {
    return false;
}


private class CameraControllerThread extends HandlerThread implements Handler.Callback{

    protected Handler mWorkerHandler;

    public CameraControllerThread(String name){
        super(name);
    }

    @Override
    protected void onLooperPrepared() {
        mWorkerHandler = new Handler(getLooper(), this);
    }

    @Override
    public boolean handleMessage(Message message) {

        switch(message.what){
            case MSG_OPEN_CAM:
                openCamera();
                break;
        }

        return true;
    }
 }
}

我想我的问题是 - 为什么我实例化我的CameraController并从onCreate发送消息 - 它允许我更新UI - 当我从{{{I}做同样的事情时1}}它不允许我?

1 个答案:

答案 0 :(得分:1)

引用Android documentation

  

[从UI线程外部访问Android UI工具包]可能导致未定义和意外的行为,这可能很难追踪并且非常耗时。

在比赛条件之后会发生任何事情。