【2】TypedArray.mData 研究

基于Android API 23源码,以 Window属性为例。

    private int[] styleableWindow = new int[]{
            android.R.attr.windowNoTitle,
            android.R.attr.windowActionBar,
            android.R.attr.windowActionBarOverlay,
            android.R.attr.windowActionModeOverlay,
            android.R.attr.windowSwipeToDismiss,
            android.R.attr.windowContentTransitions,
            android.R.attr.windowActivityTransitions
    };
Activity样式如下:

    <style name="appWindow" parent="Theme.AppCompat.Light">
        <item name="android:windowActionBar">true</item>
        <item name="android:windowNoTitle">true</item>
    </style>

测试代码:

  @SuppressWarnings("ResourceType")
    private void outT(){
        TypedArray a = this.obtainStyledAttributes(styleableWindow);

        Log.e(Tag, "TypedArray长度 = "+ a.length()+"");
        Log.e(Tag, a.toString());

        Log.e(Tag, "FEATURE_NO_TITLE---            1 = " + a.getBoolean(0, false));
        Log.e(Tag, "FEATURE_ACTION_BAR---          2 = " + a.getBoolean(1, false));
        Log.e(Tag, "FEATURE_ACTION_BAR_OVERLAY---  3 = " + a.getBoolean(2, false));
        Log.e(Tag, "FEATURE_ACTION_MODE_OVERLAY--- 4 = " + a.getBoolean(3, false));
        Log.e(Tag, "FEATURE_SWIPE_TO_DISMISS---    5 = " + a.getBoolean(4, false));
        Log.e(Tag, "FEATURE_CONTENT_TRANSITIONS--- 6 = " + a.getBoolean(5, false));
        Log.e(Tag, "FEATURE_ACTIVITY_TRANSITIONS---7 = " + a.getBoolean(6, false));

        a.recycle();
    }

输出结果:

TypedArray长度 = 7;

数组内容整理后如下:

[
18, -1, 1, 0, 1073746944, 0, 
18, -1, 1, 0, 1073746944, 0, 
0 ,  0, 1, 0,          0, 0, 
18,  0, 1, 0, 1073746944, 0, 
0 ,  0, 1, 0,          0, 0, 
18,  0, 1, 0, 1073746944, 0, 
18, -1, 1, 0, 1073746944, 0
]

属性值输出:

 FEATURE_NO_TITLE---            1 = true
 FEATURE_ACTION_BAR---          2 = true
 FEATURE_ACTION_BAR_OVERLAY---  3 = false
 FEATURE_ACTION_MODE_OVERLAY--- 4 = false
 FEATURE_SWIPE_TO_DISMISS---    5 = false
 FEATURE_CONTENT_TRANSITIONS--- 6 = false
 FEATURE_ACTIVITY_TRANSITIONS---7 = true

数据分析:
现在开始研究windowActionBar和windowNoTitle在TypedArray.mData数组中怎么表现的。

<item name="android:windowActionBar">true</item>
<item name="android:windowNoTitle">true</item>



查看TypedArray 创建代码:

    static TypedArray obtain(Resources res, int len) {
        final TypedArray attrs = res.mTypedArrayPool.acquire();
        if (attrs != null) {
            attrs.mLength = len;
            attrs.mRecycled = false;

            final int fullLen = len * AssetManager.STYLE_NUM_ENTRIES;
            if (attrs.mData.length >= fullLen) {
                return attrs;
            }

            attrs.mData = new int[fullLen];
            attrs.mIndices = new int[1 + len];
            return attrs;
        }

        return new TypedArray(res,
                new int[len*AssetManager.STYLE_NUM_ENTRIES],
                new int[1+len], len);
    }

    TypedArray(Resources resources, int[] data, int[] indices, int len) {
        mResources = resources;
        mMetrics = mResources.mMetrics;
        mAssets = mResources.mAssets;
        mData = data;
        mIndices = indices;
        mLength = len;
    }

发现,在不复用数组池的情况下,TypedArray.mData的长度 = styleable数组的长度 *AssetManager.STYLE_NUM_ENTRIES
即: styleable.length * 6

TypedArray.mData数组每6个数值表示一个属性。
测试代码中 styleableWindow [0] 表示windowNoTitle属性, styleableWindow [1] 表示windowActionBar属性.
在TypedArray.mData数组中使用下标0~5的数据表示windowNoTitle属性,6~11表示windowActionBar属性.

每6个数据中,
第0位数据表示AssetManager.STYLE_TYP—标识数据类型,0 表示 数据没有值。18 表示布尔类型,详见TypedValue
第1位数据表示 属性的值 AssetManager.STYLE_DATA
第2位数据表示 AssetManager.STYLE_ASSET_COOKIE
第3位数据表示 AssetManager.STYLE_RESOURCE_ID
第4位数据表示 AssetManager.STYLE_CHANGING_CONFIGURATIONS
第5位数据表示 AssetManager.STYLE_DENSITY

TypedArray.mData数组 0~5数据如下:

18, -1, 1, 0, 1073746944, 0, 

mData[0] = 18 表示属性为布尔类型
mData[1] = -1 根据getBoolean源码return mData[0]!= 0 ;所以返回true

暂时分析到这里,剩下的部分,看看源码就都理解了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值