Android程序结构

1. Android程序结构


2. R.java--保存res目录下的资源的ID

    • 它位于gen目录下;是ADT自动生成的文件,包含对res目录下的drawable、layout、menu和values目录内的资源的引用指针,Android程序能够直接通过R类引用目录中的资源。

    • R.java文件不能手工修改,如果向资源目录中增加或删除了资源文件,则需要在工程名称上右击,选择Refresh来更新R.java文件中的代码。

    • R类包含的几个内部类,分别与资源类型相对应,资源ID便保存在这些内部类中,例如子类drawable表示图像资源,内部的静态变量icon表示资源名称,其资源ID为0x7f020000;一般情况下,资源名称与资源文件名相同。

2.1 引用资源

     • 资源引用有两种方案:一种是在代码中引用资源;另一种是在资源中引用资源:

        1) 代码中引用资源,需要使用资源的ID,可以通过
                [R.resource_type.resource_name]或
                [android.R.resource_type.resource_name]获取资源ID

             resource_type:代表资源类型,也就是R类中的内部类名称
             resource_name:代表资源名称,对应资源的文件名或在XML文件中定义的资源名称属性
        2) 资源中引用资源,引用格式:@ [package/]type/name
            @:表示对资源的引用
            package:是包名称,如果在相同的包,package则可以省略

3. res目录

3.1 res/anim

     XML文件,它们被编译进逐帧动画(frame by frame animation)或补间动画(tweened animation)对象

3.2 res/drawable

    .png、.jpg文件,它们被编译进以下的Drawable资源子类型中:要获得这种类型的一个资源,可以使用mContext.getResources().getDrawable(R.drawable.imageId)
    注意:放在这里的图像资源可能会被aapt工具自动地进行无损压缩优化。比如,一个真彩色但并不需要256色的PNG可能会被转换为一个带调色板的8位PNG。这使得同等质量的图片占用更少的资源。所以我们得意识到这些放在该目录下的二进制图像在生成时可能会发生变化。如果你想读取一个图像位流并转换成一个位图(bitmap),请把图像文件放在res/raw/目录下,这样可以避免被自动优化。

3.3 res/layout

   被编译为屏幕布局(或屏幕的一部分)的XML文件。就是与用户交互的界面的xml文件,即各个view的排列和嵌套。

   

3.4 res/values

   可以被编译成很多种类型的资源的XML文件。

3.4.1 array.xml

   • array.xml 定义数组

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="colors">
   <item>red</item>
   <item>yellow</item>     
   <item>green</item>     
   <item>blue</item>   
</string-array>
</resources>


3.4.2 colors.xml

    •  colors.xml 定义color drawable和颜色的字符串值(color string values,   #RGB #ARGB )。

      1) 路径res/values/colors.xml 
      2) 名字可以随意定义<color name=”cname”>value</color>
      3)使用 Resourse.getValues.getColor或R.标签名."name"属性,如:R.color.cname

<?xml version="1.0" encoding="utf-8"?>
<resources>    
<color name="white">#FFFFFF</color>   
<color name="black">#000000</color>    
</resources> 


3.4.3 dimens.xml  单位资源

   •  dimens.xml定义尺寸值(dimension value)。使用Resources.getDimension()获得这些资源。

<?xml version="1.0" encoding="utf-8"?>    
<resources>    
<dimen name="dimen_name">2px</dimen>   
<dimen name="dimen_px">5px</dimen>    
<dimen name="dimen_pt">3pt</dimen>    
<dimen name="dimen_dp">3dp</dimen>    
</resources>  

3.4.4 strings.xml

   • strings.xml定义字符串(string)值。使用Resources.getString()或者Resources.getText()获取这些资源。getText()会保留在UI字符串上应用的丰富的文本样式。

     1) 定义<String  name=”sname”>value</String>
     2) 使用 Resourse.getValues.getString或R.标签名.name属性,如:R.string.sname。

<?xml version="1.0" encoding="utf-8"?>    
<resources>   
    <string name="hello">Hello World, ResrouseTestActivity!</string>    
    <string name="app_name">ResrouseTest</string>    
</resources>  

3.4.5 styles.xml

   • styles.xml 定义样式(style)对象。

3.5 res/xml/

   任意的XML文件,在运行时可以通过调用Resources.getXML()读取。

3.6 res/raw

   直接复制到设备中的任意文件。它们无需编译,添加到你的应用程序编译产生的压缩文件中。要使用这些资源,可以调用Resources.openRawResource(),参数是资源的ID,即R.raw.somefilename。

3.7 res/menu

     菜单即可以从代码中实现也可以在资源文件中配置,这里就是要描述一下第二种:

<?xml version="1.0" encoding="utf-8"?>  
<menu xmlns:android="http://schemas.android.com/apk/res/android">  
    <item    
        android:id="@+id/previous"    
        android:title="@string/previous"    
        android:enabled="false"  
        android:icon="@android:drawable/ic_media_previous"/>  
    <item    
        android:id="@+id/play_pause"    
        android:title="@string/play"    
        android:icon="@android:drawable/ic_media_play"/>  
    <item    
        android:id="@+id/next"    
        android:title="@string/next"    
        android:icon="@android:drawable/ic_menu_next"/>  
</menu>  

3.8 res/raw和assets的异同点

   • res/raw和assets的相同点:
     1) 两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。

   • res/raw和assets的不同点:
     1) res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
     2) res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹


4. assets目录

     • assets目录用来存放原始格式的文件,例如音频文件、视频文件等二进制格式文件。此目录中的资源不能被R.java文件索引,所以只能以字节流的形式读取。

     • 读取/assets目录下的文件必须指定文件的路径,如:Activity.this.getAssets().open("519.txt");打开

5. AndroidManifest.xml

      把应用程序的基本信息提交给Android系统,在应用程序的代码能够运行之前,这个信息系统必须建立。它主要包含以下内容:

     • 用Java包给应用程序命名。这个包名是应用程序的唯一标识;
     • 描述应用程序的组件---组成应用程序的Activity、Service、Broadcast Receiver以及Content Provider。它要用每个组件的实现类来命名,并向外发布对应组件功能(例如,组件所能处理的Intent消息)。这些声明会让Android系统了解应用程序中组件,以及这些组件被加载的条件。
     • 判断哪些进程是主应用程序组件。
     • 声明应用程序所必须的权限,以便能够访问被保护的API,以及能够跟其他应用程序进行交互。
     • 为了跟应用程序组件进行交互,还声明了其他要求有的权限。
     •  列出了能够提供应用程序运行时的分析和其他信息的Instrumentation类。只有在开发和测试应用程序时才在清单文件中声明这些类,在应用程序被发布之前,要删除这些类。
     • 声明应用程序所要求的最小的Android API级别。
     • 列出应用程序必须链接的外部库。

5.1 文件结构   


     AndroidManifest.xml中可包含的元素如下表所示:

<?xml version="1.0" encoding="utf-8"?>

<manifest>

    <uses-permission />
    <permission />
    <permission-tree />
    <permission-group />
    <instrumentation />
    <uses-sdk />
    <uses-configuration />  
    <uses-feature />  
    <supports-screens />  
    <compatible-screens />  
    <supports-gl-texture />  

    <application>

        <activity>
            <intent-filter>
                <action />
                <category />
                <data />
            </intent-filter>
            <meta-data />
        </activity>

        <activity-alias>
            <intent-filter> . . . </intent-filter>
            <meta-data />
        </activity-alias>

        <service>
            <intent-filter> . . . </intent-filter>
            <meta-data/>
        </service>

        <receiver>
            <intent-filter> . . . </intent-filter>
            <meta-data />
        </receiver>

        <provider>
            <grant-uri-permission />
            <meta-data />
            <path-permission />
        </provider>

        <uses-library />

    </application>

</manifest>


5.2 文件约定

5.2.1 元素

     只有<manifest>和<application>元素时必须的,而且这两个元素在文件中只能出现一次。其他元素则可以多次出现在清单中,或者根本就不出现---但是为了构建一个有意义的清单,必须要在清单中声明某些元素。
      一个元素所包含的任何声明,包括它所包含的其他元素,所有的值都是通过属性来设置的,而不是用夹在开闭元素之间的字符数据。
     相同级别的元素通常是没有顺序的。例如,<activity>、<provider>、<service>元素可以是任意顺序的。(<activity-alias>元素是个例外,它必须放在它所代表的<activity>元素的后面。)


5.2.2 属性

    在正式的定义中,所有的属性都是可选的,但是,为了达成目的,必须要给元素指定一些属性。对于真正的可选属性,会指定发生在特殊情况下的默认值或状态。
    除了<manifest>根元素的一些属性之外,其他所有属性的命名都带有android:前缀---例如,android:alwaysRetainTaskState。因为这个前缀是通用的,所以本文档在提到属性名时,通常会忽略这个前缀。

5.2.3 声明类名称

   许多元素都对应着Java对象,包括代表应用程序自己的元素<application>,以及基本的组件---<activity>、<service>、<receiver>、<provider>等。

   如果要定义子类,那么这些子类几乎总是继承以下组件类:Activity、Service、BroadcastReceiver、ContentProvider。子类是通过name属性来声明的。这个名称必须是完整Java包名。例如,下例演示了Service子类的声明方法:

<manifest . . . >
    <application . . . >
        <service android:name="com.example.project.SecretService" . . . >
            . . .
        </service>
        . . .
    </application>
</manifest>
     但是,也可以使用简略的表达方式,用”.”符号做为name属性值的第一个字符。在Android系统解析是会在”.”符号前追加包名(包名是在<manifest>元素的package属性中声明的)。下例的声明方法与上例的结果相同:
<manifest package="com.example.project" . . . >
    <application . . . >
        <service android:name=".SecretService" . . . >
            . . .
        </service>
        . . .
    </application>
</manifest>
     在启动组件时,Android会创建这个命名子类的一个实例对象。如果没有指定子类,那么就会创建一个基类的实例对象

5.2.4 多个值的设定

   如果要给一个元素指定多个值,那么几乎总是重复使用这个元素,而不是在一个元素中列出多个值。如:

<intent-filter . . . >
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.INSERT" />
    <action android:name="android.intent.action.DELETE" />
    . . .
</intent-filter>

5.2.5 资源值的设定

     有一些属性值是能够显示给用户的---例如,Activity的标题和图标。这些属性值应该被本地化,并因此要设置在资源或主题中。来自资源的值是用下列格式来表示的:

    @[package:]type:name

   如果资源与应用在同一个包中,那么package的名称可以被忽略,type是资源的类型---如“string”或“drawable”,name是标识指定资源的名称。例如:

<activity android:icon="@drawable/smallPic" . . . >
      来自主题的值是用类似的方式来表示的,但是要以‘?’开始,而不是‘@’:

    ?[package:]type:name



5.2.6 String值的设定

    当属性值是一个字符串是,‘\\’符号要用于字符转义---如‘\\n’表示在此处换行,‘\\uxxxx’表示‘xxxx’是Unicode字符。

5.3 文件功能

     以下章节介绍清单文件是如何反映Android的某些功能的。

5.3.1 Intent过滤器

     应用程序的核心组件Activity、Service、Broadcast Receiver)都是通过Intent对象来激活的。Intent对象绑定了所期望的操作的信息说明---包括要操作的数据、执行操作的组件类别、以及其他相关的指令。Android会定位一个合适的组件来响应Intent对象的请求,如果需要它启动这个组件的一个新的实例,并且把Intent对象传递给这个实例。

     组件通过Intent过滤器来公布它所具有的能力---组件所能响应的Intent对象的类型。因此Android系统在启动组件之前,必须了解组件能够处理那些Intent对象,Intent过滤器要在清单文件的<intent-filter>元素中指定。

     明确命名目标组件的Intent对象,会激活那个组件,过滤器并不扮演一个角色,但是如果没有指定目标组件名称的Intent对象要想激活一个组件,那么它必须能够通过这个组件的一个过滤器来传递。

5.3.2 图标和标题

    许多元素有icon和label属性,这两个属性能够声明显示给用户的小图标文本标签。还有一些属性有description属性,这个属性值用于在屏幕上显示一些比较长的解释性的文本。例如<permission>元素就有这三个属性,这样在用户询问是否授予应用程序所请求权限时,就可以用一个icon代表权限、label代表权限名称、description来详细说明权限的内容,并把这些信息展示给用户。

    在任何情况下,在容器型元素中设置的icon和label都会成为它所包含的所有子元素的默认的icon和label设置。这样,在<application>元素中设置的icon和label属性值就会成为每个应用程序组件的默认icon和label值。针对一个组件的icon和label设置也会有同样的效果---例如,一个<activity>元素中设置的icon和label属性值,会成这个<activity>中每个<intent-filter>元素的默认设置。如果<application>元素设置了一个label属性,但是<activity>元素以及它的<intent-filter>都没有设置这个属性,那么这个<application>元素的label属性值会作为<activity>和<intent-filter>元素的label属性的默认值。

     给Intent过滤器设置的icon和label属性被用于代表一个组件,不管什么时候,过滤器都会用这两个属性来向用户展示组件所能满足的功能。例如,带有android.intent.action.MAINandroid.intent.category.LAUNCHER操作的一个过滤器,会把对应的Activity做应用程序的启动界面来处理,也就是说,它应该作为Android应用程序启动器中一个应用程序来显示,因此这个过滤器中的icon和label的属性设置应该显示在Launcher中。

5.3.3 权限

     permission是一种约束,它限制了对设备上的数据或部分代码的访问。施加权限是为了保护关键的数据和代码不被滥用,防止给用户带来不好的用户体验。

    每种权限都会有一个唯一的标签来标识。通常,标签指明了要约束的操作。例如:

   android.permission.CALL_EMERGENCY_NUMBERS 
   android.permission.READ_OWNER_DATA 
   android.permission.SET_WALLPAPER 
   android.permission.DEVICE_POWER

   一个功能能够通过多个权限来施加保护。

     如果应用程序需要访问一个被权限保护的功能,那么它必须在清单文件中用<uses-permission>元素来声明其要求的权限。然后,在应用程序被安装到设备上时,Android安装器会通过检查应用程序的数字证书,以及询问用户,来确定是否要授予应用程序所请求的权限。如果权限请求被接受,那么应用程序就能够使用被保护的功能,否则,在试图访问那些受保护的功能时就会失败,而且不会给用户任何提示。

     应用程序也可以有保护它自己的组件(Activity、Service、Broadcast Receiver、Content Provider)。通常可以利用Android系统中定义的权限(在android.Manifest.permission类中列出的权限),也可以利用其它应用程序声明的权限,还可以定义自己的权限。用<permission>元素来声明一个新的权限。例如,一个Activity可以通过下列方法来保护:

<manifest . . . >
    <permission android:name="com.example.project.DEBIT_ACCT" . . . />
    <uses-permission android:name="com.example.project.DEBIT_ACCT" />
    . . .
    <application . . .>
        <activity android:name="com.example.project.FreneticActivity"
                  android:permission="com.example.project.DEBIT_ACCT"
                  . . . >
            . . .
        </activity>
    </application>
</manifest>
     要注意的是,在这个例子中,不仅使用<permission>元素声明了一个DEBIT_ACCT权限,而且还用<uses-permission>元素申请了一个DEBIT_ACCT权限。为了让应用程序的其他组件能够启动这个被保护的Activity,即使这种保护是应用程序自己施加的,也必须要这样申请。

     在同一个例子中,如果permission属性设置了另外一种权限(如android:permission.CALL_EMERGENCY_NUMBERS),那么就没有必要再用<permission>元素来声明它了。但是依然有必要使用<uses-permission>元素来进行必要的申请。

    <permission-tree>元素为一组在代码中定义的权限声明了一个命名空间,并且<permission-group>元素为这个权限组定义了一个标签,这个标签在向用户展示权限时,只会影响到权限的分组。<permission-group>元素没有指定哪个权限属于该组,它只是给出了一个组名。一个权限通过比较<permission>元素的permissionGroup属性值来确定其分组。

5.3.4 外部类库

    每个应用程序都会链接默认的Android类库,包括构建程序的基本程序包(如,Activity、Service、Intent、View、Button、Application、ContentProvider等等)。

   但是,有些包会驻留在它们自己的类库中,如果应用要使用这些包中的代码,就必须明确的要求链接这些类库。对于每个要链接的类库,清单文件中必须包含单独的<uses-library>元素。
























评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值