removeViewImmediate和removeView的区别

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 这是一个车站,一个早已破旧的不成样子的车站,一个已经数日里没有任何生机的车站。这是一个不知在地图上能否找到的车站,...
    天空不曾有鸟的痕迹阅读 1,839评论 0 1
  • 雾都花儿阅读 1,079评论 0 2
  • 这次作业我分为三部分,一部分是记录从『分身术』到『自律』这两节课课程的感想『认知的作用』。另外一部分才是记录『自律...
    N牛大力阅读 2,900评论 1 2
  • 1、燕子安静的睡了一个下午,到接近旁晚的时候才醒了过来。首先映入她眼帘的是,放在床头柜上散发着淡淡清香的鲜花。然后...
    听雨轩0755阅读 3,382评论 0 1