我們知道android中的view的更新(大小徐钠,位置癌刽,內(nèi)容)
全部都交給了WindowManager,其實(shí)現(xiàn)類為WindowManagerImpl有著三大方法addView尝丐,updateViewLayout显拜,removeView。由意思可以做到他們的具體功能爹袁,對應(yīng)著添加view远荠,更新view,和刪去view失息。
removeViewImmediate和removeView的區(qū)別在于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;
// 設(shè)置不攔截焦點(diǎn)
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;// 且設(shè)置坐標(biāo)系 左上角
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);
}
});
}
代碼中點(diǎn)擊start按鈕在一個(gè)新的線程中addview,顯示一個(gè)新的button,再點(diǎn)擊end按鈕在主線程中removeView刪除掉盹兢。
可以看出來完美邻梆,成功執(zhí)行,然而把windowManager.removeView(newButton);改成windowManager.removeViewImmediate(newButton);
程序奔潰掉绎秒,提示Only the original thread that created a view hierarchy can touch its views.
由于WindowManagerGlobal.checkThread檢查當(dāng)前線程是不是創(chuàng)建view的線程浦妄,是的話再在ViewRootImpl進(jìn)行刪除view處理。然而removiewImmedate是在主線程執(zhí)行的见芹,所以奔了剂娄。
而removeView異步執(zhí)行,發(fā)送一個(gè)MES_DIE消息玄呛,再由ViewRootImpl進(jìn)行刪除操作阅懦。