AssetManager

转载 2015年11月20日 16:09:30
 Android应用程序作为一种移动客户端应用程序,它同样也是毫无意外地将代码逻辑和界面资源进行分离,但是它的资源管理方式与传统的Web应用程序和PC客户端应用程序以及iOS应用程序相比会更复杂一些,这是因为Android应用程序可能会运行在各种大小和密度不等的设备之上。接下来我们就将注意力集中在Android应用程序资源的组织和管理之上。

        我们首先看Android应用程序资源的分类。Android应用程序资源可以分为两大类,分别是assets和res:

        1. assets。assets类资源放在工程根目录的assets子目录下,它里面保存的是一些原始的文件,可以以任何方式来进行组织。这些文件最终会被原装不动地打包在apk文件中。如果我们要在程序中访问这些文件,那么就需要指定文件名来访问。例如,假设在assets目录下有一个名称为filename的文件,那么就可以使用以下代码来访问它:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
AssetManager am= getAssets();    
InputStream is = assset.open("filename");  
        2. res。res类资源放在工程根目录的res子目录下,它里面保存的文件大多数都会被编译,并且都会被赋予资源ID。这样我们就可以在程序中通过ID来访问res类的资源。res类资源按照不同的用途可以进一步划分为以下9种子类型:
        --animator。这类资源以XML文件保存在res/animator目录下,用来描述属性动画。属性动画通过改变对象的属性来实现动画效果,例如,通过不断地修改对象的坐标值来实现对象移动动画,又如,通过不断地修改对象的Alpha通道值来实现对象的渐变效果。

        --anim。这类资源以XML文件保存在res/anim目录下,用来描述补间动画。补间动画和属性动画不同,它不是通过修改对象的属性来实现,而是在对象的原来形状或者位置的基础上实现一个变换来得到的,例如,对对象施加一个旋转变换,就可以获得一个旋转动画,又如,对对象实施一个缩放变换,就可以获得一个缩放动画。从数学上来讲,就是在对象的原来形状或者位置的基础上施加一个变换矩阵来实现动画效果。注意,在动画的执行过程中,对象的属性是始终保持不变的,我们看到的只不过是它的一个变形副本。

        --color。这类资源以XML文件保存在res/color目录下,用描述对象颜色状态选择子。例如,我们可以定义一个选择子,规定一个对象在不同状态下显示不同的颜色。对象的状态可以划分为pressed、focused、selected、checkable、checked、enabled和window_focused等7种。

        --drawable。这类资源以XML或者Bitmap文件保存在res/drawable目录下,用来描述可绘制对象。例如,我们可以在里面放置一些图片(.png, .9.png, .jpg, .gif),来作为程序界面视图的背景图。注意,保存在这个目录中的Bitmap文件在打包的过程中,可能会被优化的。例如,一个不需要多于256色的真彩色PNG文件可能会被转换成一个只有8位调色板的PNG面板,这样就可以无损地压缩图片,以减少图片所占用的内存资源。

        --layout。这类资源以XML文件保存在res/layout目录下,用来描述应用程序界面布局。

        --menu。这类资源以XML文件保存在res/menu目录下,用来描述应用程序菜单,例如,Options Menu、Context Menu和Sub Menu。

        --raw。这类资源以任意格式的文件保存在res/raw目录下,它们和assets类资源一样,都是原装不动地打包在apk文件中的,不过它们会被赋予资源ID,这样我们就可以在程序中通过ID来访问它们。例如,假设在res/raw目录下有一个名称为filename的文件,并且它在编译的过程,被赋予的资源ID为R.raw.filename,那么就可以使用以下代码来访问它:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
Resources res = getResources();  
InputStream is = res .openRawResource(R.raw.filename);  
        --values。这类资源以XML文件保存在res/values目录下,用来描述一些简单值,例如,数组、颜色、尺寸、字符串和样式值等,一般来说,这六种不同的值分别保存在名称为arrays.xml、colors.xml、dimens.xml、strings.xml和styles.xml文件中。
        --xml。这类资源以XML文件保存在res/xml目录下,一般就是用来描述应用程序的配置信息。

        注意,上述9种类型的资源文件,除了raw类型资源,以及Bitmap文件的drawable类型资源之外,其它的资源文件均为文本格式的XML文件,它们在打包的过程中,会被编译成二进制格式的XML文件。这些二进制格式的XML文件分别有一个字符串资源池,用来保存文件中引用到的每一个字符串,包括XML元素标签、属性名称、属性值,以及其它的一切文本值所使用到的字符串。这样原来在文本格式的XML文件中的每一个放置字符串的地方在二进制格式的XML文件中都被替换成一个索引到字符串资源池的整数值。这样做有两个好处:

        A. 文件占用更小。例如,假设在原来的文本格式的XML文件中,有四个地方使用的都是同一个字符串,那么在最终编译出来的二进制格式的XML文件中,字符串资源池只有一份字符串值,而引用它的四个地方只占用一个整数值。

        B. 解析速度更快。由于在二进制格式的XML文件中,所有的XML元素标签和属性等值都是使用整数来描述的,因此,在解析的过程中,就不再需要进行字符串解析,这样就可以提高解析速度。

        还有另外一个地方需要注意的是,每一个res资源在编译的打包完成之后,都会被分配一个资源ID,这些资源ID被终会被定义为Java常量值,保存在一个R.java文件中,与应用程序的其它源文件一起被编译到程序中,这样我们就可以在程序或者资源文件中通过这些ID常量来访问指定的资源。

         我们接下来再看应用程序资源的组织。应用程序资源的组织方式有18个维度,如图1所示:



图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资源按照以下方式来组织:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
drawable/  
drawable-en/  
drawable-fr-rCA/  
drawable-en-port/  
drawable-en-notouch-12key/  
drawable-port-ldpi/  
drawable-port-notouch-12key/  
       并且该应用程序所运行在的设置的配置情况如下所示:
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
Locale = en-GB   
Screen orientation = port   
Screen pixel density = hdpi   
Touchscreen type = notouch   
Primary text input method = 12key  
       根据图2所示的算法,Android资源管理框架按照以下步骤来选择一个drawable资源:
       Step 1. 消除与设备配置冲突的drawable目录,即drawable-fr-rCA目录,因为设备设置的语言是en-GB。

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
drawable/  
drawable-en/  
drawable-en-port/  
drawable-en-notouch-12key/  
drawable-port-ldpi/  
drawable-port-notouch-12key/  
        Step 2. 从MMC开始,选择一个资源组织维度来过渡从Step 1筛选后剩下来的目录。
        Step 3. 检查Step 2选择的维度是否有对应的资源目录。如果没有,就返回到Step 2继续处理。如果有,那么就继续往下执行Step 4。在我们这个例子中,要一直重复执行Step 2,直到检查到language这个维度时。

        Step 4. 消除那些不包含有Step 2所选择的资源维度的目录。在我们这个例子中,就是要消除那些不包含有en这个language的目录:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
drawable-en/  
drawable-en-port/  
drawable-en-notouch-12key/  
        Step 5.  继续执行Step 2、Step 3和Step 4,直到找到一个最匹配的资源目录为止,即剩下最后一个目录为止。在我们这个例子中,下一个要检查的维度是screen orienation。由于设备的screen orienation为port,因此,所有不包含有port资源维度的目录将被消除:
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
drawable-en-port/  
        最后剩下来的目录就只有drawable-en-port,因此,它就是最匹配的资源目录了,这时候所有drawable类型的资源都可以从这个目录中获取。
        注意,我们在编译和打包应用程序资源的过程中,会生成一个resources.arsc文件,这个文件记录了所有的应用程序资源目录的信息,包括每一个资源名称、类型、值、ID以及所配置的维度信息。我们可以将这个resources.arsc文件想象成是一个资源索引表,这个资源索引表在给定资源ID和设备配置信息的情况下,能够在应用程序的资源目录中快速地找到最匹配的资源。

         最后,我们可以通过图3来总结应用程序资源的编译、打包以及查找过程:



图3 应用程序资源的编译、打包以及查找过程

        通过图3我们就可以看出:

        A. 除了assets和res/raw资源被原装不动地打包进APK之外,其它的资源都会被编译或者处理。 

        B. 除了assets资源之外,其它的资源都会被赋予一个资源ID。

        C. 打包工具负责编译和打包资源,编译完成之后,会生成一个resources.arsc文件和一个R.java,前者保存的是一个资源索引表,后者定义了各个资源ID常量。

        D. 应用程序配置文件AndroidManifest.xml同样会被编译成二进制的XML文件,然后再打包到APK里面去。

        E. 应用程序在运行时通过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://blog.csdn.net/luoshengyang/article/details/8738877/

Libgdx利用Assetmanager实现图片加密

  • 2013年11月05日 13:00
  • 7.52MB
  • 下载

libgdx AssetManager 进度条

  • 2014年04月01日 12:06
  • 9.49MB
  • 下载

UE4(六) AssetManager文件资产管理以及动画批量导入

PS:在项目管理中FBX文件上传、获取、导入导出是很重要的一块内容,尤其动画FBX文件从MAX/MAYA导入UE 一:Unreal4 文件导入绝对路径和相对路径       通常文件放入C...

安卓之插件化开发使用DexClassLoader&AssetManager来更换皮肤

这篇文章主要使用DexClassLoader来实现插件化更换皮肤,即将皮肤独立出来做成一个皮肤插件apk,当用户想使用该皮肤时需下载(不需要安装)对应的皮肤插件apk 效果图【为方便测试,主要通过改变...
  • cxmscb
  • cxmscb
  • 2016年09月06日 11:08
  • 1249

轻松实现Android 更换皮肤(主题) - 资源打包为apk,使用AssetManager动态解析调用

来源:http://www.2cto.com/kf/201501/366859.html 目前很多app都具有换肤功能,可以根据用户自己的喜好定制自己的界面,比如新浪微博,网易新闻等等。...
  • hanwest
  • hanwest
  • 2015年08月26日 11:30
  • 350

提高Bitmap解析速度( Resources , BitmapFactory , AssetManager ,主题定制 )

图片是应用里面最常用的资源,在canvas里面使用需要将其解析成Bitmap的方式(例如倒影效果)。这里给出几个可能会有的场景,探讨一下如何使用: 应用主题转化:当某个应用希望换掉整个生命周期中...

Android资源管理框架(二)AssetManager创建过程

Android应用程序在运行的过程中,是通过一个称为AssetManager的资源管理器来读取打包在APK文件里面的资源文件的。在本文中,我们就将详细分析Android应用程序资源管理器的创建以及初始...

AssetManager查看asset文件中的图片

一个用到Bitmap的例子.用到技术,AssetManager,BitmapDrawable. 查看/assets/目录下图片的图片查看器 public class MainActivity ext...

Android应用程序插件化研究之AssetManager

文章首发:Android应用程序插件化研究之DexClassLoader|大利猫 最近在研究Android应用的插件化开发,看了好几个相关的开源项目。插件化都是在解决以下几个问题: 如何把插件ap...

(libgdx学习)AssetManager及进度条的绘制

进度条的绘制实际上就是根据已经加载资源的百分比来改变图片的长度 一、初始化及常见API manager.load("animation.png",Texture.class); ma...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AssetManager
举报原因:
原因补充:

(最多只允许输入30个字)