Android快速理解Activity、View及Window&WindowManager之间关系

基本概念描述:
1.Activity用户最直接接触到的,Activity维护应用程序的生命周期,它依赖于Window
2.Window表示一个窗口的概念,类似360悬浮窗的东西就需要Window来实现。依赖于WindowManager,同时绘制View(DecorView)
3.WindowManager用于添加,移除Window对象,如无法直接访问Window,对Window的访问必须通过WindowManager
4.View:视图,UI实现了KeyEvent.Callback和Drawable.Callback。
代码分析:

Activity源码
public void setContentView(@LayoutRes int layoutResID) {
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}

public Window getWindow() {
    return mWindow;
}

final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
    attachBaseContext(context);

    mFragments.attachHost(null /*parent*/);

    mWindow = new PhoneWindow(this);
    mWindow.setCallback(this);

总结:
Activity内部组合了一个Window(这是一个抽象类,具体是PhoneWindow)对象。setContentView,实际上是调用Window对象的 setContentView,所以说界面绘制全部是由Window类的实现类(PhoneWindow类)来完成的。

为啥attch优先于onCreate调用,就是由于在attch方法中,会创建window,有了window才能调用setContentView
attach方法中会调用PolicyManager.makeNewWindow()  

Activity 里面对各个窗口的管理相当复杂(任务栈、状态等等)



DecorView是一个应用窗口的根容器,它本质上是一个FrameLayout。DecorView有唯一一个子View,它是一个垂直LinearLayout,包含两个子元素,一个是TitleView(ActionBar的容器),另一个是ContentView(窗口内容的容器)

Decor view创建一个ViewRoot,ViewRoot负责协调decorview与windowmanager直接绘图、事件处理

1:这个PhoneWindow有一个“ViewRoot”,这个“ViewRoot”是一个View或者说ViewGroup,是最初始的根视图。
2:“ViewRoot”通过addView方法来一个个的添加View。比如TextView,Button等
3:这些View的事件监听,是由WindowManagerService来接受消息,并且回调Activity函数。比如onClickListener,onKeyDown等。
4. 如何把我们已经创建好的窗口通知给WindowManagerService ,以便它能够把这个窗口显示在屏幕上。




WindowManager源码:
public interface WindowManager extends ViewManager

public interface ViewManager
{
 
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

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

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

              wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE)

并且打开会话(IWindowSession),之后Window将通过该会话与WindowManager建立联系,

来看下setView方法:

         try {

        res =sWindowSession.add(mWindow, mWindowAttributes,

         getHostVisibility(), mAttachInfo.mContentInsets);

     } catch (RemoteException e) {

         mAdded = false;

        mView = null;

         mAttachInfo.mRootView =null;

         unscheduleTraversals();

         throw newRuntimeException("Adding window failed", e);

      } finally {

         if (restore) {

            attrs.restore();

         }

      }

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

这样就完成了把窗口添加到WindowManager中,并交由WindowManager来管理窗口的view、事件、消息收集处理等。

WindowManager的总结:

(1)WindowManager是外界访问Window的入口,Window的具体实现是WindowManagerService,WindowManager和WindowManagerService的交互是一个IPC过程。
(2)Android中所有的视图都是通过Window呈现的,不管是Activity、Dialog还是Toast,他们的视图实际上都是附加在Window上的,因此Window实际是View的直接管理者。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值