Winow&WindowManager

其实在android中真正展示给用户的是window和view,activity在android中所其的作用主要是处理一些逻辑问题,比如生命周期的管理、建立窗口等。在android中,窗口的管理还是比较重要的一块,因为他直接负责把内容展示给用户,并和用户进行交互。响应用户的输入等。

       在讲窗口管理时,有必要先说下ViewManager这个接口,这个接口主要有以下的实现子接口和实现类,分别是:WindowManager和ViewGroup里面还有三个重要的方法:
        * addView();
       * updateViewLayout();
       * removeView();

        在WindowManager中,addView方法表示的是将主窗口中的顶级view(也就是DecorView)添加到WindowManager中,并建立会话。接下来会详细介绍。我们先来看看Window

        Window:
       Window是android中的窗口,表示顶级窗口的意思,也就是主窗口,它有两个实现类,PhoneWindow和MidWindow,我们一般的activity对应的主要是PhoneWindow,在activity中经常使用的setContentView等方法也是在这个里面实现的。

java代码:
  1. @Override
  2. public void setContentView(View view,ViewGroup.LayoutParams params) {
  3. if (mContentParent == null) {
  4. installDecor();
  5. }else{
  6. mContentParent.removeAllViews();
  7. }

  8. mContentParent.addView(view, params);
  9. final Callback cb = getCallback();
  10. if (cb != null) {
  11. cb.onContentChanged(); //窗口类容发生变化时更新
  12. }

复制代码

       每个主窗口中都有一个View,称之为DecorView,是主窗口中的顶级view(实际上就是ViewGroup),在View中有两个成员变量叫做mParent、mChildren,它是用来管理view的上下级关系的。而ViewGroup是对一组View的管理。因此,在ViewGroup中建立了所有view的关系网。而最终ViewGroup附属在主窗口上。这样就很容易在窗口中通过findViewById找到具体的View了。view中的事件处理也是根据这个路径来处理的。

java代码:
  1. performLaunchActivity( );
  2. handleResumeActivity( ); 
复制代码

       在performLaunchActivity中,会调用activity.attach方法建立一个window, 在handleResumeActivity方法中启动activity的时候,会将主窗口加入到WindowManager中。

java代码:
  1. View decor =r.window.getDecorView(); //获得窗口的顶级View
  2. decor.setVisibility(View.INVISIBLE);
  3. ViewManager wm= a.getWindowManager(); //WindowManager继承自ViewManager
  4. WindowManager.LayoutParams l =r.window.getAttributes();
  5. a.mDecor = decor;
  6. l.type =WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
  7. l.softInputMode |= forwardBit;

  8. if (a.mVisibleFromClient) {
  9. a.mWindowAdded = true;
  10. wm.addView(decor, l); //实际上是把主窗口的顶级view加入到WindowMangaer

复制代码

       WindowManager:
       WindowManager主要用来管理窗口的一些状态、属性、view增加、删除、更新、窗口顺序、消息收集和处理等。
        通过Context.getSystemService(Context.WINDOW_SERVICE)的方式可以获得WindowManager的实例.
WindowManager继承自ViewManager,里面涉及到窗口管理的三个重要方法,分别是:
         * addView(); 
        * updateViewLayout();
        * removeView(); 

       在WindowManager中还有一个重要的静态类LayoutParams.通过它可以设置和获得当前窗口的一些属性。

我们先来看看addView()方法,在addView中,会利用LayoutParams获得window的View属性,并为每个window创建ViewRoot,ViewRoot是View和WindowManager之间的桥梁,真正把View传递给WindowManager的是通过ViewRoot的setView()方法,ViewRoot实现了View和WindowManager之间的消息传递。在将主窗口添加到WindowManger时,它首先会建立一个代理对象:

---------------------------------------------------

原来,整个Android的窗口机制是基于一个叫做 WindowManager,这个接口可以添加view到屏幕,也可以从屏幕删除view。它面向的对象一端是屏幕,另一端就是View,直接忽略我们以前的Activity或者Dialog之类的东东。其实我们的Activity或者Diolog底层的实现也是通过WindowManager,这个 WindowManager是全局的,整个系统就是这个唯一的东东。它是显示View的最底层了。

 

写一个简单的代码:

 WindowManager mWm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
        Button view = new Button(this);
        view.setText("window manager test!");
        WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); 
        mWm.addView(view, mParams);

 

我们这个button的显示和当前的运行环境基本上是无关的,当前是什么activity或者是桌面,使用这个底层的结果给你的编程带来很大的灵活性,但是要注意,显示出来就要销毁掉,这个是必须的,销毁其实就是一个remove。


--------------------------------------------------------------------------


java代码:
  1. wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE) 
复制代码

       并且打开会话(IWindowSession),之后Window将通过该会话与WindowManager建立联系,
       来看下setView方法:

java代码:
  1. try {
  2. res =sWindowSession.add(mWindow, mWindowAttributes,
  3. getHostVisibility(), mAttachInfo.mContentInsets);
  4. } catch (RemoteException e) {
  5. mAdded = false;
  6. mView = null;
  7. mAttachInfo.mRootView =null;
  8. unscheduleTraversals();
  9. throw newRuntimeException("Adding window failed", e);
  10. } finally {
  11. if (restore) {
  12. attrs.restore();
  13. }

复制代码

        在这段代码中,ViewRoot通过IWindowSession把窗口添加到WindowManager中。ViewRoot继承了Handler,实际上它的本质就是一个Handler,窗口中View的事件处理、消息发送、回调等将通过ViewRoot来处理。


 private void initDialog() {
        mDialog = new Dialog(this);
        Window window = mDialog.getWindow();
        window.requestFeature(Window.FEATURE_NO_TITLE);
        mDialog.setContentView(R.layout.activity_main);

        window.setGravity(Gravity.BOTTOM);
        window.setWindowAnimations(android.R.style.Animation_InputMethod);
        
        WindowManager.LayoutParams params = window.getAttributes();
        params.width = WindowManager.LayoutParams.FILL_PARENT;
        params.height = 300;
        mDialog.onWindowAttributesChanged(params);
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值