Android Activity源码分析--windowmanager屏幕旋转研究

注意:鄙人看的是6.0的代码

Activity里面还是调用了WindowManager来显示界面。在activity的738行,有这几行代码

    private Window mWindow;

    private WindowManager mWindowManager;
    /*package*/ View mDecor = null;  //这就是activity的主view,我也不知道怎么表达会比较好 = =

平常用的setContentView方法,最终是调用了mWindow来处理的。

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

mWindow其实一个 PhoneWindow对象,在6169行的attach方法可是看到它的初始化

    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);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        ...

}

其中mWindowManager是通过mWindow来实现初始化

mWindowManager = mWindow.getWindowManager();

接着看看activity是怎么调用mWindowManager来显示界面,在源码第4772行,可以看到一个setVisible方法,这就是activity展示界面的入口吧

    public void setVisible(boolean visible) {
        if (mVisibleFromClient != visible) {
            mVisibleFromClient = visible;
            if (mVisibleFromServer) {
                if (visible) makeVisible();//我将要展示界面
                else mDecor.setVisibility(View.INVISIBLE);
            }
        }
    }

接着看看makeVisible方法是怎么调用mWindowManager来显示界面。没错,其实就是用addview来显示界面。 

    void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }

为什么activity能通过android:configChanges="orientation|keyboardHidden" ,能保证界面不重建呢,我们可以看到源码还有一个onWindowAttributesChanged方法。

    public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
        // Update window manager if: we have a view, that view is
        // attached to its parent (which will be a RootView), and
        // this activity is not embedded.
        if (mParent == null) {
            View decor = mDecor;
            if (decor != null && decor.getParent() != null) {
                getWindowManager().updateViewLayout(decor, params);
            }
        }
    }

我估计是用了updateViewLayout来刷新页面,单纯看到这里,activity是怎么监听屏幕旋转呢?

 

转载于:https://my.oschina.net/moziqi/blog/754583

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值