java - 不能从另一个线程调用 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,但这说明了导致问题的原因。如果有,请在评论中告诉我需要编辑)
对小语法错误深表歉意
解决方案
使用处理程序延迟执行您的操作。例如:
Handler h = new Handler();
h.postDelayed(new Runnable() {
public void run() {
gameConstraintLayout.removeView(currentBullet);
}
}, 1000); // here 1000 is delay in milliseconds (1sec)
推荐阅读
- reactjs - 从子组件中获取所有选定的值
- android - 使用 Kotlin 识别 Android 软键盘中的击键
- javascript - 在循环内调用具有不同 api 参数值的相同 web api
- javascript - Xcode 10 更新后 React Native 无法正常工作
- postgresql - postgresql 中的交叉表函数导致无效的内存分配请求大小
- assembly - 编写一个 ARM 汇编语言程序来计算第 n 个斐波那契数
- prolog - 如何从问题中打印变量值?
- php - 试图将实际日期与天数相匹配
- html - 导航中的下拉菜单定位
- python - 条件语句中的 return 语句在 Python 中给出了意想不到的结果