• 源码分析结论


    由以上2.1~2.6对源码的分析,可以得到以下结论:

    3.1 Activity、Window和View的依赖关系:


    3.2 setContentView()执行的序列图:

    Activity展示的其实是PhoneWindow上的内容。那么其实 setContentView 实际上是调用的 PhonwWindow的setContentView。可以看出Window是做为中介者连接了Activity和View。

    3.3.Activity的视图框架结构(http://www.amjmh.com/v/)


    3.4 解释一下DecorView的布局资源的加载逻辑,features变量是怎么来的:

    再观察generateLaout()的实现如下:

    protected ViewGroup generateLayout(DecorView decor) {
    ...
    int layoutResource;
    int features = getLocalFeatures(); //获取的是mLocalFeatures值
    //下面是一堆用feastures值来判断改用哪个布局文件的逻辑
    if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
    layoutResource = R.layout.screen_swipe_dismiss;
    setCloseOnSwipeEnabled(true);
    } else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
    if (mIsFloating) {
    TypedValue res = new TypedValue();
    getContext().getTheme().resolveAttribute( R.attr.dialogTitleIconsDecorLayout, res, true);
    layoutResource = res.resourceId;
    } else {
    layoutResource = R.layout.screen_title_icons;
    }
    removeFeature(FEATURE_ACTION_BAR);
    }
    ...
    mDecor.startChanging();
    mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
    ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
    ...
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    那么,mLocalFeatures的值是怎么来的?直接搜索mLocalFeatures被赋值的地方,发现是通过getDefaultFeatures()方法拿到的,但是这个只是拿到默认的features值,这是不够的。反推,上面都是位操作,我们要搜索mFeatures和mLocalFeaures的位操作地方了,源码里面用一个int值代表一堆标记位的事情也不少了。果然,发现,是在PhonwWindow的requestFeature()中设置的标记位:
    public boolean requestFeature(int featureId) {
    if (mContentParentExplicitlySet) {
    throw new AndroidRuntimeException("requestFeature() must be called before adding content");
    }
    final int features = getFeatures();
    final int newFeatures = features | (1 << featureId);
    if ((newFeatures & (1 << FEATURE_CUSTOM_TITLE)) != 0 &&
    (newFeatures & ~CUSTOM_TITLE_COMPATIBLE_FEATURES) != 0) {
    throw new AndroidRuntimeException(
    "You cannot combine custom titles with other title features");
    }
    ...
    //Window的requestFeature()会将featureId通过按位或运算记录到mFeatures变量中
    return super.requestFeature(featureId);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    这样也能解释的通了,为什么在Activity中使用requestFeature()要在setContentView()前调用了,以为这个值是给Activity的DecorView选择加载那种样式的布局文件用的。如果在setContentView之后调用,这个时候PhoneWindow::generateLayout(DecorView)已经执行完成了,并不会生效。

  • 相关阅读:
    UGUI组件之Slider组件简单笔记
    UGUI事件之Drag拖拽事件
    C#的数据类型之最常用的几种类型
    UGUI组件之Text文本组件简单笔记
    UGUI组件之Toggle 组件简单笔记
    Print 与Debug.Log的区别
    Unity脚本用VS打开出现 "以下文件中的行尾不一致,要将行尾标准化吗?"
    UGUI组件之Image 组件简单笔记
    UGUI事件之Pointer指针事件
    定制自己的Unity脚本模板
  • 原文地址:https://www.cnblogs.com/ly570/p/11460295.html
Copyright © 2020-2023  润新知