TimerTask 并在 UI 线程上设置视图

TimerTask and setting Views on UI Thread

我正在尝试使用 TimerTask 检测用户长按。当用户按住按钮的时间超过 LONG_PRESS_TIMEOUT 变量时,应执行可运行代码旁边的代码。短按事件有效,但是在执行以下代码时,当调用 TimerTask 时,出现错误 Only the original thread that created a view hierarchy can touch its views.

 View.OnTouchListener detectClickAndHoldListener = new View.OnTouchListener() {

        private Timer timer = new Timer();
        private long LONG_PRESS_TIMEOUT = 1337; // TODO: your timeout here
        private boolean wasLong = false;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.d(getClass().getName(), "touch event: " + event.toString());

            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                // touch & hold started
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        wasLong = true;
                        snap.setBackgroundResource(R.drawable.cam_rec);
                        try {
                            initRecorder(mCameraView.getHolder().getSurface());
                            mMediaRecorder.start();

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        // touch & hold was long
                    }
                }, LONG_PRESS_TIMEOUT);
                return true;
            }

            if (event.getAction() == MotionEvent.ACTION_UP) {
                // touch & hold stopped
                timer.cancel();
                if(!wasLong){
                    mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
                    snap.setBackgroundResource(R.drawable.filled_cam);
                }
                else {
                    mMediaRecorder.stop();
                    mMediaRecorder.reset();
                }
                timer = new Timer();
                return true;
            }

            return false;
        }
    };
YourActivity.this.runOnUiThread(new Runnable(){
@Override
public void run(){
    try {
             initRecorder(mCameraView.getHolder().getSurface());
             mMediaRecorder.start();
    } catch (IOException e) {
         e.printStackTrace();
    }
}
);