属性资源与Android命名空间

更新: 对于自定义属性资源,如今不实用http://schemas.android.com/apk/res/<Packge name> 的形式了, 统一用 java

"http://schemas.android.com/apk/res-auto"


Android应用程序将全部的静态资源都封装在了APK文件中,并根据这些资源文件名(不包括扩展名)或key属性的值生成资源ID。这些ID将做为变量的形式被定义在R类的相应子类中。例如,全部的图像资源(res/drawable目录中的资源文件)都会在R.drawable类中生成相应的变量,变量名就是图像资源的文件名。当使用这些资源时,只要引用R类中相应的变量,系统就会知道上哪去寻找相应的资源。大多数资源的定位很好理解,例如,"@string/hello"引用了字符串资源hello。"@drawable/icon"引用了图像资源文件(多是icon.png、icon.jpg等图像)。但有一类资源的引用可能大多数初学者不太注意,这就是属性资源。android

为了解释属性资源,如今先来看一段<TextView>标签的定义代码。spa

<TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"/>

 

在这段代码中设置了android:layout_width和android:layout_height属性,咱们会发现,若是将android:layout_width改为android:layout_width1,必定是没法编译经过的。而若是不加android命名空间,能够任意设置<TextView>标签的属性,只要属性和属性值符合XML规范,就能够编译经过。例如,下面的<TextView>标签设置了test属性后,彻底能够进行正常编译。code

<TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        test="value"/>

从这一点能够判断,系统对android:layout_width属性的验证与XML自己无关。那么到底与什么有关呢?orm

实际上,android:layout_width要分开来看,首先看layout_width。系统内部有一个系统级的R.java文件,全部的系统资源生成的ID都在该文件中的R类相关子类中定义。而在这个R类中有一个attr子类,用于定义系统中全部的属性,也就是XML标签设置的属性名,而这个R类的Package就是android。xml

咱们并不须要去关心R类的代码,由于这个R类是在Android源代码编译时自动生成并编译的,Android源代码和Android SDK中并无这个R类的源代码。不过读者能够随便找一个Android工程,选择Android 4.2开发包(也能够是其余版本),很容易就能够找到R类及其attr子类,如图8-12黑框中所示。资源

在attr类中有不少咱们已经很熟悉的成员变量,例如,layout_width、layout_height就是attr类中的两个变量。那么这个属性资源有什么用呢?开发

系统在检测XML标签属性时,若是能够肯定某一个R类的位置,就会认为当前XML标签的属性名必须与R.attr类中某个变量名一致,不然会认为该属性有误。那么系统又是如何肯定R类的位置呢?字符串

答案固然是android命名空间了,也就是说android命名空间会直接指定这个内嵌在系统中R类的位置。下面看一下android命名空间的定义。get

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
……> 
……  
</RelativeLayout>

咱们能够看到,android命名空间的值是一个Url形式的字符串,不过这个Url是有必定规则的。这个Url的通用形式以下:
 

http://schemas.android.com/apk/res/<Package Name>

也就是说这个Url有一个叫"http://schemas.android.com/apk/res/"的前缀,后面跟的内容就是R类的Package名。结合前面android命名空间的定义可知,Package名就是android。而前面已经提到过,系统内嵌的R类的Package就是android。因此经过这个android命名空间,系统就能够知道R类的全名(Package Name + Class Name),因此就能够直接定位了 。

尽管android命名空间的值不能修改,不过android命名空间的名称是能够修改的,例如,下面的<TextView>标签的设置是合法的。
 

<RelativeLayout xmlns:mobile="http://schemas.android.com/apk/res/android"     ……>     <TextView     
        mobile:layout_width="wrap_content"     
        mobile:layout_height="wrap_content"/> 
</RelativeLayout>

假设在当前应用程序中R类的Package是www.mobile.com,而且要引用R类中属性资源,那么命名空间应该按以下方式设置。
 

<RelativeLayout 
    xmlns:mobile="http://schemas.android.com/apk/res/www.mobile.com" ……>
     ……  
</RelativeLayout>

固然,属性资源还不单单能限制属性名,还能够约束属性值,

相关文章
相关标签/搜索