TypedArray的初略探索

TypedArray a = obtainStyledAttributes(R.styleable.Gallery);
Log.i(TAG,"a " + a + " -> \n" + a.getIndexCount() + " \n" + a.length() + " \n" + R.styleable.Gallery.length);
mGalleryItemBackground = a.getResourceId( R.styleable.Gallery_android_galleryItemBackground, 0);
Log.i(TAG,"mGalleryItemBackground " + mGalleryItemBackground);
a.recycle(); 


附:
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="Gallery">
    <attr name="android:galleryItemBackground" />
  </declare-styleable> 
</resources>


<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="Gallery">
    <attr name="android:galleryItemBackground" />
    <attr name="galleryItemBackground" format="reference" />
    <attr name="backgroundDimEnabled" format="boolean" />
  </declare-styleable> 
</resources>


1.TypedArray a = obtainStyledAttributes(R.styleable.Gallery);
Retrieve styled attribute information in this Context's theme。
从当前的上下文theme中返回styled的属性值。
那到底是什么意思呢?


进入Context.java
public final TypedArray obtainStyledAttributes(
            int[] attrs) {
        return getTheme().obtainStyledAttributes(attrs);   -----1
    }
先看 getTheme()
public abstract Resources.Theme getTheme();
在ContextImp.java实现getTheme()
    @Override
    public Resources.Theme getTheme() {
        if (mTheme == null) {
            mThemeResource = Resources.selectDefaultTheme(mThemeResource,
                    getOuterContext().getApplicationInfo().targetSdkVersion);   ----2
            mTheme = mResources.newTheme();   ---3
            mTheme.applyStyle(mThemeResource, true);   ---4
        }
        return mTheme;
    }
大概看下2
Resources.java
public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
        return selectSystemTheme(curTheme, targetSdkVersion,
                com.android.internal.R.style.Theme,
                com.android.internal.R.style.Theme_Holo,
                com.android.internal.R.style.Theme_DeviceDefault);
    }
此时的curTheme=0;targetSdkVersion=10
public static int selectSystemTheme(int curTheme, int targetSdkVersion,
            int orig, int holo, int deviceDefault) {
        if (curTheme != 0) {
            return curTheme;
        }
        if (targetSdkVersion < Build.VERSION_CODES.HONEYCOMB) {
            return orig;
        }
        if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            return holo;
        }
        return deviceDefault;
    }
根据上面的数据,返回orig,即com.android.internal.R.style.Theme


看3,mTheme = mResources.newTheme();
mResources在init就有值,所以不会有空指针问题。
    public final Theme newTheme() {
        return new Theme();
    }
简单理解就是为了实例化mTheme,不深入了。
看4,mTheme.applyStyle(mThemeResource, true);
即为mTheme.applyStyle(com.android.internal.R.style.Theme, true);
        public void applyStyle(int resid, boolean force) {
            AssetManager.applyThemeStyle(mTheme, resid, force);
        }
哦,又多了一个mTheme,其实这个是刚才不深入的地方,还是简单进入看下
private final int mTheme;
        Theme() {
            mAssets = Resources.this.mAssets;
            mTheme = mAssets.createTheme();
        }
权当mTheme有值了。再下去就涉及JNI了。
不过AssetManager的applyThemeStyle这个函数也是在底层实现的。
android_util_AssetManager.cpp
简单看:
{ "applyThemeStyle", "(IIZ)V",(void*) android_content_AssetManager_applyThemeStyle },


static void android_content_AssetManager_applyThemeStyle(JNIEnv* env, jobject clazz,
                                                         jint themeInt,
                                                         jint styleRes,
                                                         jboolean force)
{
    ResTable::Theme* theme = (ResTable::Theme*)themeInt;
    theme->applyStyle(styleRes, force ? true : false);
}
上面那个pplyStyle函数就不看了(c++部分薄弱)


回到1:obtainStyledAttributes(attrs)
public TypedArray obtainStyledAttributes(int[] attrs) {
            int len = attrs.length;
            TypedArray array = getCachedStyledAttributes(len);
            array.mRsrcs = attrs;
            AssetManager.applyStyle(mTheme, 0, 0, 0, attrs,
                    array.mData, array.mIndices);
            return array;
        }
private TypedArray getCachedStyledAttributes(int len) {
	return new TypedArray(this,
                    new int[len*AssetManager.STYLE_NUM_ENTRIES],
                    new int[1+len], len);
}
返回一个TypedArray 
算一算这个Array的大小:len=1;AssetManager.STYLE_NUM_ENTRIES=6;
new int[6],new int[2],1
还是没能把TypedArray形象化,就是知道它是包含数据的容器。目前就就此记录下,备后续再看。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值