美文网首页Android技术知识程序员Android开发
removeViewImmediate和removeView的区

removeViewImmediate和removeView的区

作者: elick耶 | 来源:发表于2018-10-18 21:40 被阅读11次

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

    相关文章

      网友评论

        本文标题:removeViewImmediate和removeView的区

        本文链接:https://www.haomeiwen.com/subject/hnzszftx.html