首页 > 解决方案 > 不能从另一个线程调用 constraintLayout.remove();

问题描述

可以说我有一个ImageView点击执行的 a Button

 final ImageView ball = new ImageView(v.getContext());
 ball.setImageResource(R.drawable.ball_1);
 gameConstraintLayout.addView(ball);

当我单击该按钮时,它首先使球出现,创建并运行另一个线程,告诉自己休眠 1000 毫秒sleep(long millis),然后通过调用移除球ConstrainLayout.removeView(view)

这是完整的最小代码:

        final ImageView ball = new ImageView(v.getContext());
        currentBullet.setImageResource(R.drawable.ball_1);
        gameConstraintLayout.addView(ball);

        ballAppears.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            final ImageView ball = new ImageView(v.getContext());
            currentBullet.setImageResource(R.drawable.ball_1);
            gameConstraintLayout.addView(ball);

            Thread thread = new Thread() {
                @Override
                public void run() {
                    try {
                        sleep(1000);
                        contraintLayout.removeView(ball)
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

            });


        }
    });

问题是;

球出现在屏幕上,另一个线程成功休眠了 1000 毫秒,但是,当它试图从另一个线程的约束布局中移除球时,它崩溃了。

日志猫:

    android.view.ViewRootImpl$CalledFromWrongThreadException: **Only the original thread that created a view hierarchy can touch its views**.

  at  android.support.constraint.ConstraintLayout.removeView(ConstraintLayout.java:645)
    at  com.mobilegames.***.******.GameActivity$1$1.run(GameActivity.java:51)

导致问题的代码是:

gameConstraintLayout.removeView(ball_1);

看起来,我无法从另一个线程访问约束布局,但我仍然可以更改球的 X 和 Y。

我什至尝试在 UI 中运行那段代码runOnUIThread(...),但无济于事。

这是 runONUIThread 代码:

       shootTank.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            final ImageView currentBullet = new ImageView(v.getContext());
            currentBullet.setImageResource(R.drawable.bullet_model1);
            gameConstraintLayout.addView(currentBullet);

            Thread thread = new Thread() {
                @Override
                public void run() {
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    runOnUiThread(new Runnable() {
                        public void run() {
                            gameConstraintLayout.removeView(currentBullet);
                        }
                    });


                }
            };
            thread.start();

        }
    });

任何可能的解决方案?请记住,我每秒都会更改球的 X 和 Y。

是的,我确实检查了其他问题。那些回答说只是在 UI 线程上运行它,但我当然已经尝试过了。如果我将 sleep(long millis) 运行到 UI 线程中,那么整个应用程序将是不负责任的。

(这不是完整的应用程序;它被分解为一个更简单和易于理解的问题。我最终在单独的线程中更改了球的 X 和 Y,但这说明了导致问题的原因。如果有,请在评论中告诉我需要编辑)

对小语法错误深表歉意

标签: javaandroidmultithreading

解决方案


使用处理程序延迟执行您的操作。例如:

Handler h = new Handler();
h.postDelayed(new Runnable() {
   public void run() {
       gameConstraintLayout.removeView(currentBullet);
   }
}, 1000);  // here 1000 is delay in milliseconds (1sec)

推荐阅读