Android资源管理框架(Asset Manager)简要介绍和学习计划
Android应用程序主要由两部分内容组成:代码和资源。资源主要就是指那些与UI相关的东西,例如UI布局、字符串和图片等。代码和资源分开可以使得应用程序在运行时根据实际需要来组织UI。这样就可使得应用程序只需要编译一次,就可以支持不同的UI布局。这种特性使得应用程序在运行时可以适应不同的屏幕大小和密度,以及不同的国家和语言等。在本文中,我们就简要介绍Android的资源管理框架,以及制定学习计划。
老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!
在软件开发中,说到代码与资源分离,最容易想到的可能就是Web开发了。在Web开发中,我们一般会通过CSS文件来描述HTML页面的展现形式,也就是通过CSS来控制HTML页面的UI。这样就可以很方便地进行Web开发和维护。例如,当我们要更改HTML页面的UI时,只要修改相应的CSS文件就可以了。注意,这些CSS文件都是在运行时加载的。这样我们就可以根据HTML页面的运行环境来加载不同的CSS文件,例如,根据不同的地区或者语言来选择不同的CSS文件,从而实现国际化。
再来看PC客户端软件的开发。开始的时候,微软的MFC应用程序框架非常流行。在开发MFC程序的时候,代码和资源同样也是分开的,例如,程序的界面一般都是通过一个RC文件来描述的。不过我们一般都是在Visual Studio里面通过可视化界面来编辑RC文件的,即一般都不会直接手动去操作RC文件,所以我们一般都不怎么意识到其实RC文件和CSS文件一样,都是用来描述程序的界面的。实际上,RC文件和CSS文件一样,都是可以看作是一个界面配置文件,而且它们的配置信息都是通过文字来描述的,只不过这些文字描述要遵循一定的规范。
随着PC客户端软件的发展,微软的MFC应用程序框架显得有些力不从心了,其中的一个原因就是它的界面比较丑陋。如果要对MFC应用程序的UI进行美化以及个性化的话,是要费比较大的劲的,这严重地影响了软件开发效率,特别是不适合要进行快速迭代开发的互联网客户端软件。微软后来又开发了另外一套应用程序开发框架WPF。WPF同样是使用一种称为XAML的文件来描述应用程序的界面的。实际上,包括现在Win 8的Metro界面,也同样是通过XAML文件来描述应用程序界面的。XAML文件是一种XML文件,它具有更好的可读性,非常方便编辑以及维护。
在PC客户端软件的发展过程中,还有一种不得不提的应用程序框架——QT。QT最初由Trolltech公司开发,后来被Nokia收购。随着Meego的没落,如日冲天的Nokia也没落了,Qt又被卖给了芬兰的另外一家IT服务公司Digia。QT也算得是一套优秀的应用程序框架,而且它是跨平台的。QT同样也是通过一种称为QML的文件来描述应用程序的界面的,不过QML文件不是XML格式的,它的格式有点类似Web页面的CSS。
类似这种采用XML文件来描述界面的PC客户端软件开发框架其实还有很多,例如,迅雷用的Bolt界面引擎,以及腾讯QQ用的GF界面引擎,它们都同样是通过XML文件来描述程序界面的,并且做成代码和界面描述文件分离。
最后看iOS应用程序的开发,它的界面和代码同样是分开,并且通过一种称为XIB的文件来描述界面。XIB文件实际上也是一个XML文件,因此,它也是非常方便编辑以及维护的。
从上面的分析就可以看出,无论是Web应用程序,还是PC客户端应用程序,以及移动客户端应用程序,它们都无一例外地将代码与界面分离,并且界面都是通过描述性的文字来描述的,这种描述性的文字越来越倾向于使用XML格式。
Android应用程序作为一种移动客户端应用程序,它同样也是毫无意外地将代码逻辑和界面资源进行分离,但是它的资源管理方式与传统的Web应用程序和PC客户端应用程序以及iOS应用程序相比会更复杂一些,这是因为Android应用程序可能会运行在各种大小和密度不等的设备之上。接下来我们就将注意力集中在Android应用程序资源的组织和管理之上。
我们首先看Android应用程序资源的分类。Android应用程序资源可以分为两大类,分别是assets和res:
1. assets。assets类资源放在工程根目录的assets子目录下,它里面保存的是一些原始的文件,可以以任何方式来进行组织。这些文件最终会被原装不动地打包在apk文件中。如果我们要在程序中访问这些文件,那么就需要指定文件名来访问。例如,假设在assets目录下有一个名称为filename的文件,那么就可以使用以下代码来访问它:
图1 应用程序资源的组织方式
注意,图1的表格是来自于官方文档的,它的详细描述可以参考:http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources。这里有一点需要说明的是,表格中的18个维度是按照优先级从最大到小排列的,这个优先级次序可以帮助系统根据机器的本地配置来在应用程序资源目录中找到最合适的资源来使用。
具体来说,Android资源管理框架按照图2所示的算法流程来在应用程序资源目录中选择最合适的资源:

图2 应用程序资源的匹配算法
注意,图2的算法流程图是来自于官方文档的,它的详细描述可以参考:http://developer.android.com/guide/topics/resources/providing-resources.html#BestMatch。我们同样是通过上述官方文档中的例子来说明上述应用程序资源匹配算法的执行过程。
假设一个应用程序的drawable资源按照以下方式来组织:
图3 应用程序资源的编译、打包以及查找过程
通过图3我们就可以看出:
A. 除了assets和res/raw资源被原装不动地打包进APK之外,其它的资源都会被编译或者处理。
B. 除了assets资源之外,其它的资源都会被赋予一个资源ID。
C. 打包工具负责编译和打包资源,编译完成之后,会生成一个resources.arsc文件和一个R.java,前者保存的是一个资源索引表,后者定义了各个资源ID常量。
D. 应用程序在运行时通过AssetManager来访问资源,或通过资源ID来访问,或通过文件名来访问。
在接下来的一系列文章中,我们主要关注以下三个关键情景:
1. 应用程序资源的编译和打包过程;
2. 应用程序资源的初始化过程;
3. 应用程序资源的查找过程。
通过这个三个情景,我们基本上就可以了解Android系统的资源管理框架了,敬请关注。不过在阅读这个系列的文章之前,希望读者可以先了解一下Android应用程序资源的基础知识,因为这个系列的文章不会陷入到这些基础知识中去,具体可以参考以下官方文档:
A. http://developer.android.com/guide/topics/resources/index.html。
B. http://developer.android.com/guide/practices/screens_support.html。
老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!