首先我们应该知道android应用中逻辑和视图是相互分离的,他主要包括两大部分:逻辑层(逻辑代码)和视图层(界面布局)两个部分。在web编程中,web页
面就是视图层,逻辑层则在后台服务器,在web页面中web的UI是通过css文件来进行控制的,在android中UI则是通过xml文件来进行控制,由于android硬
件的多样性,android页面的UI控制则显得稍微复杂,资源管理也不同于web编程。下面我们来简单剖析一下android的资源管理。
在android程序资源中,可以分为assets和res两大类:
一、assets:当我们新建一个android工程项目时,会自动生成一个assets的空文件。他主要是用来存放一些原始的视频音频等文件,在apk
进行资源打包时,会将这些文件原封不动的打包进apk中,他们在apk中没有资源ID,如果需要访问这些文件,按照下面的方式即可访问:
AssetManager am= getAssets();
InputStream is = assset.open("filename");
二、res:res文件目录及其子目录包含了应用中所有的资源文件,如:image 文件,layout文件,以及string文件等等,他主要分为以下几种:
1、animator/:这个文件中主要保存那些属性动画文件(不断改变动画对象的坐标值,来达到动画的效果),当新建一个动画文件时,会在R.java文件中为
他分配一个资源ID。
2、anim/:这个文件中主要是用来保存一些补间动画文件(所谓补间动画就是,只要我们定义动画的开始及结束图像,中间过程的动画效果通过系统提供
的算法自动生成,当然如果我们要实现更为复杂的动画效果,那么中间的动画这需要单独去实现),当新建一个文件时,也会在R.java文件中为其分配一
个资源ID。
3、color/:这个文件中用来保存定义颜色对象状态的xml文件,其中颜色对象有以下几种属性:state_pressed,state_focused,state_selected,
state_checkable,state_checked,state_enabled,state_window_focused。新建一个文件时,也会在R.java文件中为其分配一个资源ID。
4、drawable/:这个文件中是用来保存一些资源图片或者图片相关的xml文件的,主要有以下几种类型:图片资源(Bitmap files),
.9.png(Nine-Patches (re-sizable bitmaps)),状态列表(State lists)文件,层叠样式文件(Layer List),淡入淡出效果样式文件(Transition Drawable),嵌
入样式文件(Inset Drawable),剪切样式效果文件(Clip Drawable),Scale Drawable样式文件,Shape Drawable样式文件。也就是说所有的普通图片以
及一些图片样式文件是放在这个文件下的。
5、layout/:页面布局文件。
6、menu/:定义程序菜单的xml文件。
7、raw/:任意的文件都可以保存在这个文件夹下,你能够使用Resources.openRawResource()通过资源ID来访问文件的InputStream,文件ID通过
R.raw.filename来进行获取。但是如果想通过原始的文件名来进行访问,则应该将文件放入到assets文件夹下,raw文件夹中的文件系统会为其分配资源ID。
8、values/:这个文件中主要用来保存一些颜色,数组,尺寸,字符串,样式值等xml文件。他们分别保存在arrays.xml,colors.xml,dimens.xml,
strings.xml,styles.xml文件中。
9、xml/:这个文件夹中主要保存一些android不存在的一些类型的xml文件,如:一些配置信息的xml文件。
以上的资源文件类型就是android中所有的资源文件类型了,除了assets文件夹中的文件不会被分配资源ID,其余的都会被系统分配一个资源ID,除了
raw文件夹下的文件以及drawable文件夹下的图片文件不是xml格式外,其余的都是以xml文件来表示的。在打包的过程中这些文件会被编译成二进制
格式的xml文件,这些二进制格式的xml文件有一个字符串池,用来保存xml文件中用到的字符串,这样原先在xml文件中的字符串就会被替换为到字符
串池某个字符的索引字符串池中的字符是唯一的。这样就能够达到节省内存的效果,原先多个相同的字符在不同的文件中都占有一份内存,现在在字
符串池中被一个字符就能保存。
由于android平台的特殊性,为了适配不同的屏幕,有些资源文件并不能够适配所有不同分辨率的屏幕。所以在资源加载时必须提供不同的资源文件
让系统根据屏幕特点去选择相应的资源。所以android提供了以下相应等级的选择规则来加载图片。
(说明:图片引用网上) android资源加载规则。
这些规则的优先级是由高到低,可以参考官方APIhttp://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources。
这些规则怎样使用呢?拿一个图片资源为例:如果你想适配多种屏幕。
1、首先你得构造不同分辨率的图片,都给其相同的命名,在资源文件夹res下创建几个drawable文件夹。
2、对这几个文件夹按照上述规则进行命名,各种规则之间用破折号(—)进行隔开,如:drawable-port-hdpi,drawable-land-dpi。其中优先级高的必须
处在优先级低的左边。否则系统在进行资源加载时会忽略此文件。
3、将之前构造好的不同分辨率的图片放入不同的文件夹下。
这样系统在加载资源时,会根据文件夹的命名规则去选择相应的资源进行加载以达到适配的目的。
在这样的限定符名字的规则下(Qualifier name rules),如果两种规则有时候对资源的要求没有区别,那么也要将资源分别放到不同规则下的文件下,这样
就会导致一个问题:同一份资源被放置两份,这样必然会导致apk包不必要的增大,那么怎样解决这个问题呢?这就需要提到别名资源(alias resources):
1、假如需要的相同资源为icon.png,将icon.png更改名字后icon_cg.png(只要不是icon.png就行)放入默认的drawable目录下。
2、分别在两个不同规则的文件夹下,创建相同名字的xml文件icon.xml。
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/icon_cg" />
其他的资源文件别名创建请参考官方API,如上链接。
3、在这两个xml文件中都引用drawable目录下的icon_cg.png。
这样创建两个xml文件就能够存储一个版本的资源文件。
下面就来就一个例子来说说android 应用资源选择算法:
这个算法他分为五个逻辑部分:
1、消除与机器配置相冲突的资源文件,到步骤2。
2、确定下一个匹配规则表中的规则A。
3、看是否有任何资源目录匹配这个规则A,如果有跳到第4步,没有则跳到第2步。
4、消除不匹配上述规则的资源目录。
5、重复步骤2,直到只有一个资源目录剩下。
拿一个例子来说,drawable 资源文件按照以下规则来进行组织:
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
机器配置信息如下:
Locale = en-GB
Screen orientation = port
Screen pixel density = hdpi
Touchscreen type = notouch
Primary text input method = 12key
一、比较机器配置信息和本地可选择的资源,由于机器设置的语言为en-GB,所以去除与en-GB相冲突的资源文件drawable-fr-rCA/,剩下:
drawable/
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
二、在规则表中,从MCC开始,挑选符合机器配置信息的规则,如果没有则继续执行此步骤,这个步骤的意思就是在机器的配置信息中挑选出符合优先级
从高到低的规则,也就是按照规则表的规则优先级,依次与机器的信息进行匹配,跳到第三步。
三、如果规则表中的A规则在机器信息中没有,如果没有则返回步骤二查看B规则在规则表中有没有,如果有跳到第四步。
四、去除不匹配B规则的资源目录,剩下:
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
重复上述步骤,最后就只剩下资源目录:drawable-en-port/。因此drawable-en-port就是最优的匹配资源了。
下面放一张,apk在打包时,有哪些东西被打包进apk了。
ps(图引用其他博客的)。
参考博客:Android资源管理框架(Asset Manager)简要介绍和学习计划