Perry G
Perry G

Reputation: 91

why is my HandlerThread updating the UI

I am currently practicing HandlerThread in Android with an easy camera example - the problem is if i create my CameraController object in onCreate and send a message to the Handler Thread in order to process my openCamera() method ( which contains direct UI update code)

It is allowing me to updated the UI although i shouldn't be allowed to do that - since technically I`m supposed to be in a different thread.

If I move the code onCheckedChanged method (it is commented in the below snippet) the application will crash saying that I am trying to update the UI thread from a different thread.

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

I guess my question is - why if I instantiate my CameraController and send the message from onCreate - it is allowing me to update the UI - and when i do the same thing from the onCheckedChangeListener it does not allow me?

Upvotes: 3

Views: 347

Answers (1)

nandsito
nandsito

Reputation: 3852

Quoting Android documentation:

[Accessing the Android UI toolkit from outside the UI thread] can result in undefined and unexpected behavior, which can be difficult and time-consuming to track down.

Anything can happen after a race condition.

Upvotes: 2

Related Questions