Android基础二 ---- Android程序基本说明
这篇是基础篇,不想看的可以直接跳到第三篇--Android开发环境搭建
我们想在Android系统中开发应用程序,这一篇就介绍一下Android系统应用程序的一些基本知识。这一篇特别长,大家耐心看吧。参考Android官方文章:
http://developer.android.com/guide/topics/fundamentals.html
目录
1.Android系统中的应用程序如何运行
2.Android应用程序的组件
3.如何启动触发组件
4.Manifest文件
5.应用程序资源
1.Android系统中的应用程序如何运行
Android程序格式
首先说明,Android系统中的应用程序是用JAVA语言编写的(虽然现在发布了支持C语言的NDK,但是可供使用的API有限,比如没用提供界面方面的API,所以无法完成一个完整的应用程序)。然后Android SDK中有工具可以将JAVA源码和其它的资源文件一起打包成一个后缀为.apk的文件,apk文件可以用来在Android系统中安装。
Android程序运行环境
每个Android程序运行在一个沙箱中,大家可以想象成每个JAVA程序是运行在自己的JVM中的。
下面有几点说明:
①Android是一个多用户系统,但是这个用户不是Windows或者Linux里面说的用户。在Android中,
每个应用程序代表一个用户。
②Android为每个应用程序分配一个唯一的用户ID。系统会为应用程序中的所有文件设置权限,只有分
配了对应用户ID的应用程序才可以访问这些文件。
③每个进程运行在独立的JVM中,所以每个应用程序与其它程序都是隔离开的。
④每个应用程序都运行在自己的线程中。当应用程序的任何组件需要执行时,系统都启动这个进程。当
程序不再运行时,系统就关闭这个进程(当系统内存太小的,也会关闭这个进行)。
综上所述,Android实现了最小权限原则。每个应用程序只能访问它工作时需要访问的模块,系统的其它模块,这个应用程序没有访问权限。这样保证了系统环境是安全的。
既然如此,每个应用程序运行在自己的进程中,而进程运行在独立的JVM中,所以各个应用程序之间是独立的。如果应用程序之间想发生联系,或者应用程序想要访问系统中的其它组件怎么办呢?
①如果想让两个应用程序发生联系,比如共享数据。可以为这两个应用程序分配同一个用户ID,这
样它们就可以共享数据了。为了节省系统资源,这两个程序会运行在同一个进程中,共享同一个JVM
②如果想让应用程序访问系统中的其它组件,比如访问SD卡,使用WI-FI等,都必须给应用程序加上
访问权限,不然不能访问。
2.应用程序组件
组件是应用程序的基本组成部分。Android应用程序由4大组件组成,每个组件都有非常明确的作用和自己的生命周期,定义什么时候创建这个组件,什么时候销毁。
Activities
Activity是Android应用程序最重要的组件,一个Acitivty就代表一个用户界面。一个应用程序一般会有多个界面,比如一个电子邮件应用会包括邮件列表页面,读邮件页面,写邮件页面等等,那么每个界面就是一个Acitivty,或者叫活动窗口,多个Activities组成了一个电子邮件程序的完整界面。同一个程序中的Acitivies之间可以相互切换,甚至程序中的Acitivity也可以启动其它程序中的Acitivity。
毫无疑问,每个应用程序都需要和用户交互,没有Acitivty就没有界面。一个Activity是一个Acitivity类的子类的实例。所以如果想创建一个Activity,那么需要一个Acitivity类的子类。
Services
Service我觉得大家一看就明白了,是运行在后台的服务,通常是一些比较耗时的操作或者远程操作。Service没有界面。最典型的比如音乐播放服务,下载服务。通常是通过Acitivity来启动一个Serivce,比如点击服务器音乐列表中的某项来开始播放服务器上的音乐。
和Activity一样,创建Service首先首先一个Service类的子类,然后实例化这个类。
Content providers
这个Content provider是做什么的?简单来讲就是管理共享数据的。前面说过,应用程序是相互独立的,多个应用程序可以共享数据。数据可以是存放在数据库中,网络上或者存在文件中。通过Content provider,应用程序可以访问这些数据,比如一个应用可以访问和修改通讯录数据,其它程序也可以访问和修改,他们需要通过Content provider来完成访问和修改操作。
Broadcast receivers
直译为广播接收者,功能也差不多,接收广播并作出响应。什么是广播呢?就是当发生一些事件的时候,Android系统会广播这个事情给大家(应用程序),比如接到一个电话,收到一个短信,电池电量低,这些都算事件。如果一个应用程序定义了Broadcast receiver,那么就可以接受这个广播,并针对这个广播事件作出一定的反应。当然广播也并不是全都由Android系统发出来的,应用程序本身也可以发广播,比如一个下载程序,当它下载完一些文件时,可以发送广播告诉其它应用程序文件已经下载完毕,你们可以来用这个文件了。
Broadcast receiver也不提供界面,通常是在状态栏出现一个通知,告诉用户发生了什么事情。Broadcast receiver更像是一个通向其它组件的入口,比如一个短信程序,当Android系统接收到一个短信时,这个短信程序的Broadcast receiver会接受系统广播,然后在状态栏出现一段文字告诉用户有短信了。用户点击这个通知的时候,会跳转到查看短信的Acitivty。
将程序分成一个一个组件还有一个好处,就是应用程序可以启动另外一个应用程序的组件,这也是Android系统的一个独特设计。举个例子,如果系统中已经有了一个应用程序可以完成拍照功能。当你在开发一个新的应用程序又需要拍照功能时,你就不必再开发一个新的拍照功能,直接使用那个应用程序的拍照组件就好了。不用将照相机的代码合并入我们的应用程序,直接在我们的应用程序中启动那个照相机程序的Activity,然后拍照即可。当拍照完成时,照片可以返回给你的应用程序,这样你的应用程序就可以使用它了。看起来那个拍照功能组件就是你程序的一部分。
3.触发组件
Activity, service, broadcast receiver这三个组件,都是通过一个叫做Intent的东西来触发启动的。举例,当我们想在某个Activity中去启动另外一个Activity时,就必须使用Intent来完成。可以将Intent想象成为一个信使,在Activities之间传递消息。
创建Intent需要使用Intent对象,在Intent中会定义去启动一个指定的组件(可以是一个特定的Activity或特定的Service)或是一种类型的组件。
如果Intent的目标是Activity或Service,Intent中需要定义目标要执行什么动作,并且可能会指定一些数据。比如在一个Acitivity中发起一个Intent,去触发另一个Acitivity去打开一个网页。那么需要定义目标Activity执行打开网页的动作,还要指定打开哪一个网页。
如果Intent的目标是Broadcast receiver,Intent通常只包含被广播的信息(比如这个广播中包含的信息是"电池电量低",那么所有能接受这个广播的Broadcast receiver就都被触发了)。
至于具体方法这里先不写了,写上了大家看了也没什么概念。
4. Manifest文件
下面注意啦!!!!!!!!!!!!!!!!!!!!
在Android开发中,有一个非常重要的文件叫做Manifest.xml文件。manifest在英文中是清单,货单的意思,在Android开发中我们需要将我们写好的组件在manifest文件中定义好(包括Activity,Service,Content Provider等等)。这个manifest文件在创建Android工程时,eclipse会自动创建好这个文件。我们只需要按规则将我们的组件写进去就好了。还有一点就是这个manifest文件必须是处在项目的根目录下。
除了在manifest文件中声明组件,manifest文件还有其它功能,如下:
1.为这个应用程序定义权限。前面说过,如果应用程序要访问Android系统的一些服务,必须要先声明权限。比如这个程序如果需要使用WI-FI功能,那么一定要先在manifest文件中为应用程序加上访问Wi-Fi的权限。
2.声明应用程序需要的API版本,或者理解为操作系统版本,比如2.0,3.0,4.0等等。
3.声明应用程序需要的硬件和软件。比如这个应用程序需要使用摄像头,那么需要在manifest中声明。
4.如果应用程序需要一些额外的API库(不属于Android Framework内的API),比如Google Map API库。
作用一. 如何在manifest文件中声明组件?
manifest文件的首要任务就是声明组件,告诉Android系统这个应用程序到底有哪些组件。
下面这段代码演示如何在application中添加两个activity,一个Service:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:icon="@drawable/app_icon.png" ... >
<activity android:name="com.example.project.ExampleActivityOne"
android:label="@string/example_label" ... >
</activity>
<activity android:name="com.example.project.ExampleActivityTwo"
android:label="@string/example_label" ... >
</activity>
<service android:name="com.example.project.ExampleServiceOne"
android:label="@string/example_label" ... >
</service>
...
</application>
</manifest>
可以看到一对application标签,里面包含两对activity标签和一对service标签,表示这个程序里面共有两个activity和一个service。
<activity>
元素表示activities
<service>
元素表示services
<receiver>
元素表示broadcast receivers
<provider>
元素表示content providers
作用二. 这个词组我真的不知道怎么翻译(Declaring component capabilities),大家直接看正文吧
在第3节--触发组件 中提到,Android如果想要启动触发Activity,Service,Broadcast receiver需要用到Intent。可以在Intent中明确地定义到底要启动哪一个组件,只要制定组件的类名就好了。比如有个Service叫做TestService,这个TestService肯定是继承Service类的,所以在Intent中只要写入TestService的名字就可以了。
但是对于一个Intent对象来讲,最核心的东西是一个叫做action的属性。这个action属性,我们只要指明它的类型就可以了(还可以指定这个action需要操作的数据),系统会找到可以执行这个action的组件并启动它。如果有不止一个组件这个执行这个action,那么由用户来选择使用哪一个。
系统怎么知道哪些组件可以执行这个action呢?或者说哪个组件可以响应这个intent呢? 这个是通过一个叫intent-filter的属性来定义的,这个属性是在manifest文件中定义的。下面代码演示如何为组件添加intent-filter:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:icon="@drawable/app_icon.png" ... >
<activity android:name="com.example.project.ExampleActivityOne"
android:label="@string/example_label" ... >
<intent-filter . . . >
<actionandroid:name="android.intent.action.EDIT"/>
<actionandroid:name="android.intent.action.INSERT"/>
<actionandroid:name="android.intent.action.DELETE"/>
</intent-filter>
</activity>
...
</application>
</manifest>
这个intent-filter是定义在activity中的,定义了这个activity可以接受哪些类型的intent, 这里定义了这个activity可以接受EDIT,INSERT,DELETE这三种类型的intent。前面说过了,intent的核心属性就是action,而我们在定义一个intent对象的时候需要指定这个action属性的类型。在activity中可以用intent-filter来定义这个activity可以接受哪些类型的intent。如果类型匹配,就可以接受这个intent,否则不能。 所以总结一下intent-filter就是定义activity可以响应哪种类型的intent。
现在有点理解Declaring component capabilities该怎么翻译了。应该是声明组件的能力,它到底能做什么,能接受哪些intent。
作用三. 声明应用程序的硬件软件需求
玩过游戏的同学们都知道,安装游戏的时候都有一个最低配置要求,就是你的电脑的硬件和软件配置不能低于最低要求,否则不能安装,或者安装上了也跑不起来。Android应用程序对硬件和软件也有配置要求。现在Android手机型号这么多,不同手机的配置也不一样,有高有低。系统也不一样,有2.1,2.2,3.0等等,所以我们需要为我们的应用程序定义软硬件配置。但是在manifest文件中定义了这些信息以后呢,Android系统不去读这个信息。这个信息实际上是给Android应用商店使用的,应用商店读取软硬件配置信息后,会显示给用户,让用户知道如果想安装使用这个应用程序,需要什么样的手机配置。
举例,比如我们有一个拍照程序,并且使用了2.1的Framework API。那么毫无疑问,用户的手机必须得有摄像头,并且用户手机搭载的Android系统版本必须高于2.1。我们在manifest文件中定义了这些信息,Android应用商店会读取这些信息,告诉用户如果你的机器不满足这些要求是不能安装的。如果你不在manifest中定义这些信息,那么用户可以随意安装,但是在运行程序的时候才会发现机器不满足要求,所以还是建议写上,不然安装后发现根本用不了,用户火更大...
5.应用程序资源
应用程序不光是由源代码组成,还需要其它的比如图片,视频,音频等,我们把它们统称为资源文件。当我们需要这些资源文件的时候,在其它开发中,比如像WEB开发,一般是直接引用这个资源文件所在的地址。但是在Android开发中,我们不采用引用资源文件地址的方式,而是我们为每一个资源文件赋予一个ID,当需要使用资源文件直接引用这个ID就可以了。
具体如何引用这里先不讲了,这篇太长了,内容多了也不容易记,先到这吧。