我们知道android中的view的更新(大小,位置,内容)
全部都交给了WindowManager,其实现类为WindowManagerImpl有着三大方法addView,updateViewLayout,removeView。由意思可以做到他们的具体功能,对应着添加view,更新view,和删去view。
removeViewImmediate和removeView的区别在于removeViewImmediate为同步删除removeView为异步删除。
private void initView() {
final Button newButton=new Button(MainActivity.this);
Button button=findViewById(R.id.start);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
windowManager = (WindowManager) MainActivity.this.getSystemService(WINDOW_SERVICE);
newButton.setText("it was created");
params = new WindowManager.LayoutParams();
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
// 设置不拦截焦点
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
params.width = (int) (60 * getResources().getDisplayMetrics().density);
params.height = (int) (60 * getResources().getDisplayMetrics().density);
params.gravity = Gravity.LEFT | Gravity.TOP;// 且设置坐标系 左上角
params.format = PixelFormat.TRANSPARENT;
int width = windowManager.getDefaultDisplay().getWidth();
int height = windowManager.getDefaultDisplay().getHeight();
params.y = height / 2 - params.height / 2;
windowManager.addView(newButton, params);
Looper.loop();
}
}).start();
}
});
Button button1=findViewById(R.id.end);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
windowManager.removeView(newButton);
}
});
}
代码中点击start按钮在一个新的线程中addview,显示一个新的button,再点击end按钮在主线程中removeView删除掉。
1.gif
可以看出来完美,成功执行,然而把windowManager.removeView(newButton);改成windowManager.removeViewImmediate(newButton);
image.png
程序奔溃掉,提示Only the original thread that created a view hierarchy can touch its views.
由于WindowManagerGlobal.checkThread检查当前线程是不是创建view的线程,是的话再在ViewRootImpl进行删除view处理。然而removiewImmedate是在主线程执行的,所以奔了。
而removeView异步执行,发送一个MES_DIE消息,再由ViewRootImpl进行删除操作。
网友评论