Android应用程序资源分析

发布时间 : 星期三 文章Android应用程序资源分析更新完毕开始阅读

Android应用程序资源分析

在Android系统中,每一个应用程序一般都会配置很多资源,用来适配不同密度、大小和方向的屏幕,以及适配不同的国家、地区和语言等等。这些资源是在应用程序运行时自动根据设备的当前配置信息进行适配的。这也就是说,给定一个相同的资源ID,在不同的设备配置之下,查找到的可能是不同的资源。这个资源查找过程对应用程序来说,是完全透明的。在本文中,我们就详细分析资源管理框架是如何根据ID来查找资源的。

从前面Android应用程序资源管理器(Asset Manager)的创建过程分析一文可以知道,Android资源管理框架实际就是由AssetManager和Resources两个类来实现的。其中,Resources类可以根据ID来查找资源,而AssetManager类根据文件名来查找资源。事实上,如果一个资源ID对应的是一个文件,那么Resources类是先根据ID来找到资源文件名称,然后再将该文件名称交给AssetManager类来打开对应的文件的,这个过程如图1所示。

图1 应用程序查找资源的过程示意图

在图1中,Resources类根据资源ID来查到资源名称实际上也是要通过

AssetManager类来实现的,这是因为资源ID与资源名称的对应关系是由打包在APK里面的resources.arsc文件中的。当Resources类查找的资源对应的是一个文件的时候,它就会再次将资源名称交给AssetManager,以便后者可以打开对应的文件,否则的话,上一步找到的资源名称就是最终的查找结果。

从前面Android应用程序资源的编译和打包过程分析一文可以知道,APK包里面的resources.arsc文件是在编译应用程序资源的时候生成的,然后连同其它被编译的以及原生的资源一起打包在一个APK包里面。

从前面Android资源管理框架(Asset Manager)简要介绍和学习计划一又可以知道,Android应用程序资源是可以划分是很多类别的,但是从资源查找的过程来看,它们可以归结为两大类。第一类资源是不对应有文件的,而第二类资源是对应有文件的,例如,字符串资源是直接编译在resources.arsc文件中的,而界面布局资源是在APK包里面是对应的单独的文件的。如上所述,不对应文件的资源只需要执行从资源ID到资源名称的转换即可,而对应有文件的资源还需要根据资源名称来打开对应的文件。在本文中,我们就以界面布局资源的查找过程为例,来说明Android资源管理框架查找资源的过程。

我们知道,每一个Activity组件创建的时候,它的成员函数onCreate都会被调用,而在Activity组件的成员函数onCreate中,我们基本上都无一例外地调用setContentView来设置Activity组件的界面。在调用Activity组件的成员函数setContentView的时候,需要指定一个layout类型的资源ID,以便Android资源管理框架可以找到指定的Xml资源文件来填充(inflate)为Activity组件的界面。接下来,我们就从Activity类的成员函数

setContentView开始,分析Android资源管理框架查找layout资源的过程,如图2所示。

图2 类型为layout的资源的查找过程

这个过程可以分为22个步骤,接下来我们就详细分析每一个步骤。 Step 1. Activity.setContentView

1. 2. 3. 4. 5.

public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory, Window.Callback, KeyEvent.Callback,

OnCreateContextMenuListener, ComponentCallbacks { ......

6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.

private Window mWindow; ......

public Window getWindow() { return mWindow; }

.....

public void setContentView(int layoutResID) { getWindow().setContentView(layoutResID); }

...... }

这个函数定义在文件frameworks/base/core/java/android/app/Activity.java中。 从前面Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析一文可以知道,Activity类的成员变量mWindow指向的是一个PhoneWindow对象,因此,Activity类的成员函数setContentView实际上是调用PhoneWindow类的成员函数setContentView来进一步操作。

Step 2. PhoneWindow.setContentView

1. 2. 3. 4.

r

public class PhoneWindow extends Window implements MenuBuilder.Callback { ......

// This is the view in which the window contents are placed. It is eithe // mDecor itself, or a child of mDecor where the contents go. private ViewGroup mContentParent; ......

private LayoutInflater mLayoutInflater; ......

@Override

public void setContentView(int layoutResID) { if (mContentParent == null) { installDecor(); } else {

5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.

联系合同范文客服:xxxxx#qq.com(#替换为@)