北京seo顾问服务公司,优化seo公司哪家好,杭州网站优化推荐,页面设计时最好使用一种颜色2019独角兽企业重金招聘Python工程师标准 做Android应用的人都知道#xff0c;要一个apk适用多个不同的手机屏幕是很容易的#xff0c;就是在项目的res文件夹下面有多套相关的资源文件。程序运行的 时候#xff0c;Android系统会根据当前设备的信息去加载不同… 2019独角兽企业重金招聘Python工程师标准 做Android应用的人都知道要一个apk适用多个不同的手机屏幕是很容易的就是在项目的res文件夹下面有多套相关的资源文件。程序运行的 时候Android系统会根据当前设备的信息去加载不同文件夹下的资源文件。但是Android系统是怎么做到这一点的呢上网上搜了一下很少有这方 便的介绍只好自己研究下代码了。下面是我研究代码得到的结果正确性有待确认在这里分享一下。 这里以ICS上在Activity的onCreate()方法里面调用setContentView(int resourceID)为例介绍一下系统如何根据我们的idR.layout.xxxx找到合适的layout文件进行解析加载 如果你的res下面有三种不同的layoutlayout, layout-sw480dp和 layout-sw600dp这里的swNdp表示这个layout文件夹下面的布局文件只有在设备短边的最小宽带为N时才加载。你的 设备是800x480的分辨率那么这个apk安装在你的设备上就会加载 layout-sw480dp里面的布局文件。下面是framework的 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-swNdp由此可见ResTable::getEntry()是我们这个问题的关键 3) 在ResTable::getEntry()里面 a) 首先获取本设备的configurion信息屏幕分辨率屏幕大小locale横竖屏等。 b) 根据得到的本设备的configurion信息过滤掉不适应本设备的entry比如设备是800x480的那么超过此分辨率的资源 (例layout-sw600dp)就要被过滤掉实现在frameworks/base/include/utils /ResourceTypes.h中ResTable_config的match函数中 c) 对过滤后的resource进行最佳适配找到最符合的entry文件。因为之前已经将不符合的即大分辨率的entry已经被过滤掉了所以这里就找剩 下的最大的就是最佳适配的。实现在frameworks/base/include/utils/ResourceTypes.h中 ResTable_config的isBetterThan()函数中。 3. 我做了一个尝试就是想让800x480分辨率的设备上的应用都加载 layout-sw600dp里面的资源文件。所以将上面b步骤的 frameworks/base/include/utils/ResourceTypes.h里面ResTable_config的match函数改动 如下 /*if (smallestScreenWidthDp ! 0 smallestScreenWidthDp settings.smallestScreenWidthDp){ return false; }*/ if (smallestScreenWidthDp ! 0 smallestScreenWidthDp 600) { return false ; } 我将settings.smallestScreenWidthDp强制换成了600这样的话所有比600dp小的包含600在内的资源文 件在做过滤时就被保留了下来而c步骤不做检查只找最大的所以layout-sw600dp就成了系统认为的“最合适”的资源问价了。 将重新编译frameworks/base/libs/utils/生成的lib库push到/system/libs下面再重启手机然后启动上述应用就可以了看见程序加载的layout-sw600dp的ui了。 转载于:https://my.oschina.net/zhuzihasablog/blog/205455