无法从另一个线程调用constraintLayout.remove();

时间:2018-10-06 22:18:05

标签: java android multithreading

假设我有一个ImageView,只需单击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毫秒,但是,当它试图从另一个线程的约束布局中删除球时,它崩溃了。

Logcat:

    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。

我什至尝试在用户界面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线程上运行它,但是我当然已经尝试过了。显然,如果我将睡眠(长毫秒)运行到UI线程中,则整个应用程序将是不负责任的。

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

对不起,语法错误

1 个答案:

答案 0 :(得分:2)

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

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