Android技术知识程序员Android开发

removeViewImmediate和removeView的区

2018-10-18  本文已影响11人  elick耶

我们知道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进行删除操作。

上一篇下一篇

猜你喜欢

热点阅读