【问题标题】:Only the original thread that created a view hierarchy can touch its views.只有创建视图层次结构的原始线程才能接触其视图。
【发布时间】:2015-04-11 10:23:41
【问题描述】:

Main Activity Oncreate Method 每当我尝试运行此代码时,它都会给我这个错误,尽管我已经添加了 runonui Thread 。但它仍然没有工作任何帮助将不胜感激。我已经搜索了很多,但真的没有找到任何东西

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

       dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
        DevicePolicyAdmin = new ComponentName(this,
                Dprcv.class);

  //      btntake =(Button)findViewById(R.id.takepicture);
        truitonAdminEnabledCheckbox = (CheckBox) findViewById(R.id.checkBox);
//start

    //    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        getWindow().setFormat(PixelFormat.UNKNOWN);
        surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        controlInflater = LayoutInflater.from(getBaseContext());
        View viewControl = controlInflater.inflate(R.layout.control, null);
        ViewGroup.LayoutParams layoutParamsControl
                = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                ViewGroup.LayoutParams.FILL_PARENT);
        this.addContentView(viewControl, layoutParamsControl);


            final Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
            buttonTakePicture.setOnClickListener(new Button.OnClickListener(){

                @Override
                public void onClick(View arg0) {
                    // TODO Auto-generated method stub

                    camera.takePicture(myShutterCallback,
                            myPictureCallback_RAW, myPictureCallback_JPG);
                }


            });
        runOnUiThread(new Runnable() {
            @Override
            public void run() {

                final Button buttonTakePicture = (Button)findViewById(R.id.takepicture);

        Thread tr = new Thread(){
            public void run(){
                try{

                    final Button buttonTakePicture = (Button)findViewById(R.id.takepicture);

                    sleep(5000);
                    buttonTakePicture.performClick();

                }
                catch (InterruptedException ex)
                {
                    ex.printStackTrace();
                }
            }
        };
        tr.start();



            }
        });

这是logcat

04-11 15:19:49.629    6343-6360/com.ahmed.raja.wrongclick E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-4119
    Process: com.ahmed.raja.wrongclick, PID: 6343
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6669)
            at android.view.ViewRootImpl.playSoundEffect(ViewRootImpl.java:5642)
            at android.view.View.playSoundEffect(View.java:17278)
            at android.view.View.performClick(View.java:4462)
            at com.ahmed.raja.wrongclick.MainActivity$2$1.run(MainActivity.java:107)

【问题讨论】:

  • 据我推断,封闭的可运行在 UI 线程上运行(正如您使用 runOnUiThread())但在该可运行的运行方法中,您正在创建另一个线程(线程 tr),并尝试访问其中的 UI 元素。因此,您会遇到此异常。

标签: android multithreading android-runonuithread


【解决方案1】:
Thread tr = new Thread(){
        public void run(){
            try{
                final Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
                sleep(5000);
                buttonTakePicture.performClick();
            }
            catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    };

performClick 必须在 ui 线程上调用,这就是您收到异常的原因。如果您想在调用performClick 之前模拟5 秒等待,您可以使用按钮的处理程序及其postDelayed 方法:

final Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.postDelayed(new Runnable() {
    public void run() {
         buttonTakePicture.performClick();
    }
}, 5000);

【讨论】:

  • 所以我不必用户 runonui ??
  • 你可以使用runOnUiThread,但你必须在正确的地方使用它。在您的情况下,您是在告诉 ui 线程启动一个执行 performClick 的新线程
【解决方案2】:

这是因为你在调用 tr.start() 时在 runOnUiThread 方法中启动了新线程;这意味着这段代码:

                    final Button buttonTakePicture = (Button)findViewById(R.id.takepicture);

                sleep(5000);
                buttonTakePicture.performClick();

不在 ui 线程中运行。据我了解,您希望执行点击延迟的代码。您可以通过以下方式进行:

buttonTakePicture.postDelayed

【讨论】:

    猜你喜欢
    • 2012-12-26
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多