移动云

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 13204|回复: 1

关于Android里资源文件加载

[复制链接]
发表于 2012-5-15 18:08:29 | 显示全部楼层 |阅读模式
本帖最后由 freesky 于 2012-5-15 18:09 编辑

不同的屏幕指标,配置等,Android会自动去加载相应的资源文件。

Android资源文件到底是加载layout,还是layout-mdpi,还是layout-sw600dp是由frameworks/base/libs/utils/ResourceTypes.cpp控制的,这里面的getResource方法里会调用getEntry,而getEntry方法里面会通过调用match方法先做一次过滤,然后遍历剩下的符合条件的文件夹里最合适的一个(通过调用isBetterThan方法)。

match方法,isBetterThan等都是去比较一些参数,其中屏幕相关的又smallestWidth, density等。

简单记录下,回头有时间再细说。
回复

使用道具 举报

 楼主| 发表于 2012-5-16 14:31:52 | 显示全部楼层
当应用程序在Activity里面调用setContentView(int resourceID)的时候,Android系统是如何为应用加载不同的资源文件完成适配的?

下面是java层的调用链:
Activity.setContentView(int resourceID) -> PhoneWindow.setContentView(int resourceID) -> LayoutInflater.inflate(int resource, ViewGroup root) -> LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot) -> Resources.getLayout(int id) -> Resources.loadXmlResourceParser(int id, String type) -> Resources.getValue(int id, TypedValue outValue, boolean resolveRefs) -> AssetManager.getResourceValue(int ident, int density, TypedValue outValue, boolean resolveRefs) -> AssetManager.loadResourceValue(int ident, short density, TypedValue outValue,  boolean resolve)

在上面的掉用链中:
1. 最后加载的是哪个xml是由Resources.getValue(int id, TypedValue outValue, boolean resolveRefs)调用完成之后的outValue.string决定的,因为outValue.string的值就是你的资源文件的具体路径, 如:
1) xxx/values/xxx.xml
2) xxx/layout-sw600dp/xxx.xml

2. AssetManager.loadResourceValue()调的是frameworks/base/core/jni /android_util_AssetManager.cpp里面的native方法, 如何获得正确的outValue值,在native方法俩面主要有一下几步:
1) 调用frameworks/base/libs/utils/ResourceTypes.cpp 的ResTable::getResource(),遍历所有资源文件
2) 在ResTable::getResource()里面调用ResTable::getEntry()来确定资源文件来自哪个entry,即 layout,或者layout-sw<N>dp,由此可见,ResTable::getEntry()是我们这个问题的关键。
3) 在ResTable::getEntry()里面:
    a) 首先获取本设备的configurion信息
    b) 根据得到的本设备的configurion信息,过滤掉不适应本设备的resource,比如设备是800x480的,那么超过此分辨率的资源 (例:layout-sw600dp)就要被过滤掉,实现在frameworks/base/include/utils /ResourceTypes.h中ResTable_config的match函数中
    c) 多过滤后的resource进行最佳适配,找到最符合的resource文件。因为之前已经将不符合的,即大分辨率的resource过滤掉了,所以这里 就找剩下的最大的就可以了。实现在frameworks/base/include/utils/ResourceTypes.h中 ResTable_config的isBetterThan()函数中。

在Android系统里面,平板相关的UI一般都在layout-sw<N>dp里面,这里的N有一般是600或720。表示要求设 备窄边的分辨率不小于600dp.

为使3Q显示平板的UI,我们尝试着将向面b)中过滤resource时,与resoure资源相比的 smallestScreenWidthDp值有设备自身的值强制改成了600,编译过后刷进手机进行尝试,是可以工作的。
Before:
            if (smallestScreenWidthDp != 0
                    && smallestScreenWidthDp > settings.smallestScreenWidthDp) {
                return false;
            }

After:
            if (smallestScreenWidthDp != 0
                    && smallestScreenWidthDp > 600) {
                return false;
            }
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|管理员QQ:44994224|邮箱(t268studio@gmail.com)|Archiver|MCLOUDER

GMT+8, 2025-7-2 05:49 , Processed in 0.044097 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表