Android应用程序核心-应用程序的基本组件

Android应用程序没有唯一的启动入口(如C语言中的main()函数入口),一个Android应用程序是由多个不同的组件组合而成,组件之间通过Intent来实现通信。

    Android系统的基本组件包括Activity,Service, BroadcastReceiver和ContentProvider等,此外还包括专门负责在基本组件之间传递消息的Intent组件。所有组件都必须在AndroidManifest.xml文件中声明。   

一、Activity —— 应用表示层( 基类 Activity )

    一个活动表示一个可视化的用户界面,关注一个用户从事的事件。例如,一个活动可能表示一个用户可选择的菜单项列表,或者可能显示照片连同它的标题。一个文本短信应用程序可能有一个活动,显示联系人的名单发送信息;第二个活动,写信息给选定的联系人;其他活动,重新查看旧信息或更改设置。虽然他们一起工作形成一个整体的用户界面,但是每个活动是独立于其他活动的。每一个都是作为Activity基类的一个子类的实现。

     应用程序中的每个屏幕都是通过继承和扩展基类 Activity 来实现的。  

     同一应用中的每个 Activity 是相互独立的。程序启动后显示的第一幅画面是应用程序的第一个 Activity (默认窗口),而后可以根据需要从这个 Activity 启动另一个新的 Activity 。  

     Activity 利用 View 来实现应用中的 GUI (用户直接通过 GUI 和应用程序做交互)。 Activity 窗口内的可见内容通过基类 View 提供。使用 Activity.setContentView() 方法设置当前 Activity 中的 View 对象。

l          每个 View 对象控制着窗口内的一个矩形空间;

l          View 是一种层次化结构, Parent View 中的布局属性会被子 View 继承;

l          位于 View 层次关系最底层的子 View 对象所代表的矩形空间就是跟用户进行交互的地方

 

Activity 状态回调:

l          onCreate

l          onStart

l          onRestart

l          onResume

l          onPause

l          onStop

l          onDestroy

 

二、Service —— 没有可见的用户界面,但能够长时间运行于后台( 基类 Service )

    一个服务没有一个可视化用户界面,而是在后台无期限地运行。例如一个服务可能是播放背景音乐而用户做其他一些事情,或者它可能从网络扩取数据,或计算一些东西并提供结果给需要的活动(activities)。每个服务都继承自Service基类。

     运行于应用程序进程的主线程中,因此 Service 不会阻塞其他组件和用户界面。

     Service 是不能自己启动的,必须通过 Context 对象(如一个 Activity )调用 startService 或 bindService 方法来启动(用这两种方法启动的 Service 的生命周期不同)。

1. 调用 startService 方法

a) 若 Service 没有启动,则首先会调用该 Service 的 onCreate 方法,然后再调用 onStart 方法。

b) 若 Service 已经启动,则会直接调用 onStart 方法

c) 该方法启动的 Service ,可以通过 Context 对象调用 stopService 来关闭,也可以通过 Service 自身调用 stopSelf() 或 stopSelfResult() 来关闭,关闭之前调用 onDestory 方法。

2.调用 bindService 方法,使当前 Context 对象通过一个 ServiceConnection 的对象绑定到所指定的 Service

a)若 Service 没有启动,则首先会调用该 Service 的 onCreate 方法初始化启动,然后调用 Service 的 onBind 方法初始化绑定。

b)如果绑定 Service 的 Context 对象被销毁时,被绑定的 Service 也会调用 onUnbind 和 onDestroy 方法停止运行

c)注意: BroadcastReceiver 是不能绑定服务的。

d)一个绑定 Service 的 Context 对象还可以通过 unbindService() 来取消对服务的绑定。

e)取消时, Service 会调用 unbind 方法,若 Service 是通过 bindService 来启动的,还会调用 onDestroy 方法来停止服务。

       Service 状态回调:

l          onCreate

l          onStart

l          onBind

l          onRebind

l          onUnbind

l          onDestroy

 

三、Broadcast Receiver —— 用户接收广播通知的组件( 基类 BroadcastReceiver )

     一个广播接收者是这样一个组件,它不做什么事,仅是接受广播公告并作出相应的反应。许多广播源自于系统代码,例如公告时区的改变、电池电量低、已采取图片、用户改变了语言偏好。应用程序也可以发起广播,例如为了他其他程序知道某些数据已经下载到设备且他们可以使用这些数据。一个应用程序可以有任意数量的广播接收者去反应任何它认为重要的公告。所有的接受者继承自BroadcastReceiver基类。

    Android 中的广播要么来自于系统,要么来自普通应用程序。

很多事件都可能导致系统广播,如手机所在时区发生变化,电池电量低,用户改变系统语言设置等。

来自普通应用程序,如一个应用程序通知其他应用程序某些数据已经下载完毕。

    为了响应不同的事件通知,应用程序可以注册不同的 Broadcast Receiver 。所有的 Broadcast Receiver 都继承自基类 BroadcastReceiver 。

    BroadcastReceiver 自身并不实现图形用户界面,但是当它收到某个通知后, BroadcastReceiver 可以启动 Activity 作为响应,或者通过 NotificationMananger 提醒用户。

    BroadcastReceiver 是对发送出来的 Broadcast 进行过滤接收并响应的一类组件。

 

   发送 Broadcast 信息

1. 把要发送的信息和用于过滤得信息 ( 如 Action 、 Category) 装入一个 Intent 对象

2. 调用 Context. sendBroadcast() 、 sendOrderBroadcast() 、 sendStickyBroadcast() 方法,广播该 Intent 对象

3. 使用 sendBroadcast() 或 sendStickyBroadcast() 方法发出去的 Intent ,所有满足条件的 BroadcastReceiver 都会随机地执行其 onReceive() 方法;

4. 而 sendOrderBroadcast() 发出去的 Intent ,会根据 BroadcastReceiver 注册时 IntentFilter 设置的优先级的顺序来执行,相同优先级的 BroadcastReceiver 则是随机执行

5. sendStickyBroadcast() 方法主要的不同是, Intent 在发送后一直存在,并且在以后调用 registerReceiver() 注册相匹配的 Intent 时会把这个 Intent 直接返回。

6. 若在使用 sendBroadcast() 方法时指定了接收的权限,这只有在 AndroidManifest.xml 中用 标签声明了拥有此权限的 BroadcastReceiver 才会有可能接收到发送来 Broadcast 。

7. 若在注册 BroadcastReciever 时,指定了可接收的 Broadcast 的权限,则只有在包内的 AndroidManifest.xml 中用 标签声明了,拥有此权限的 Context 对象所发送的 Broadcast 才有可能被这个 BroadcastReceiver 所接收。

  接收 Broadcast 消息

1. 继承 BroadcastReceiver 类,并实现 onReceive 方法

2. 注册 Broadcast Receiver (有 2 种方法:一种方法是,静态地在 AndroidManifest.xml 中用 标签声明,并在标签内用 标签设置过滤器; 另一种方法,动态地在代码中先定义并设置好一个 IntentFilter 对象,然后再需要注册的地方调用 Context.registerReceiver() 方法) (取消注册时,调用 Context.unregisterReceiver() 方法)

 

四、Content Provider 为解决应用程序间数据通信、共享的问题(基类 ContentProvider )

    内容提供者(content provider)使一个应用程序的指定数据集提供给其他应用程序。这些数据可以存储在文件系统中、在一个SQLite数据库、或以任何其他合理的方式。内容提供者继承自ContentProvider 基类并实现了一个标准的方法集,使得其他应用程序可以检索和存储数据。然而,应用程序并不直接调用这些方法。相反,替代的是它们使用一个ContentResolver对象并调用它的方法。ContentResolver能与任何内容提供者通信,它与提供者合作来管理参与进来的进程间的通信。

     在 Android 中,每个应用程序都是用自己的用户 ID 并在自己的进程中运行。这样的好处是,可以有效地保护系统及应用程序,避免被其他不正常德应用程序所影响,每个进程都拥有独立的进程地址空间和虚拟空间。

     Content Provider 可以将应用程序特定的数据提供给另一个应用程序使用。其数据存储方式可以是 Android 文件系统、 SQLite 数据库或者其他合理的方式。

     当数据需要在应用程序间共享时,我们就可以利用 ContentProvider 为数据定义一个 URI 。之后,其他应用程序对数据进行查询或者修改时,只需要从当前上下文对象获得一个 ContentResolver, 然后传入响应的 URI 就可以了。

    Content Provider 继承自基类 ContentProvider ,并且实现了一组标准接口。通过这组接口,其他应用程序能对数据进行读写和存储。然而,需要使用数据的应用程序并不是直接调用这组方法,而是通过调用 ContentResolver 对象的方法来完成。 ContentResolver 对象可以与任意 ContentProvider 通信。

    要为当前应用程序的私有数据定义 URI ,就需要专门定义一个继承自 ContentProvider 的类,然后根据不同的操作调用的方法去实现这些方法的功能。

    ContentResolver 类为应用程序提供了接入 Content 机制的方法。要构造一个 ContentResolver 对象可以为构造方法 ContentResolver(Context context) 传入一个 Context 对象,也可以直接通过 Context 对象调用 getContentResolver() 方法获得 —— 有的 ContentResolver 对象后,就可以通过调用其 query() 、 insert() 、 update() 等方法来对数据进行操作了。

 

    一旦需要以上 4 种 Android 应用程序基本组件完成请求, Android 会首先确认该组件所在进程是否运行,如果没有运行, Android 将先启动进程,同时确认被请求组件的实例是否存在,否则将创建一个新的组件实例。

 

五、Intent —— 连接组件的纽带

    以上 4 种基本组件中,除了 Content Provider 是通过 Content Resolver 激活外,其他 3 种组件 Activity 、 Service 和 Broadcast Receiver 都是由 Intent 异步消息激活的。

    Intent 在不同的组件之间传递消息,将一个组件的请求意图传给另一个组件。因此,Intent 是包含具体请求信息的对象。

针对不同的组件,Intent 所包含的消息内容有所不同,且不同组件的激活方式也不同, 且不同类型组件有传递 Intent 的不同方式。

    Intent 是一种运行时绑定( runtime binding )机制,它能够在程序运行的过程中连接两个不同的组件。通过 Intent,你的程序可以向 Android 表到某种请求或者意愿, Android 会根据意愿的内容选择适当的组件来处理请求。

  • 激活一个新的 Activity ,或者让一个现有的 Activity 执行一个新的操作,可以通过调用如下两种方法 ( 这两汇总方法需要传入的 Intent 参数称为 Activity Action Intent) :

1. Context.startActivity()

2. Activity.startActivityForResult()

  • 启动一个新的服务,或者向一个已有的服务传递新的指令,可以调用如下两种方法:

1.  Context.startService()

2.  Context.bindService()

  • 发送广播 Intent( 所有已注册的拥有与之相匹配 IntenFilter 的 BroadcastReceiv 就会被激活 ) ,可以调用如下三种方法:

1. Context.sendBroadcast()

2. Context.sendOrderBroadcast()

3. Context.sendStickBroadcast()

     Intent 一旦发出,Android 都会准确找到相匹配的一个或多个 Activity,Service 或BroadcastReceiver 作响应。所以,不同类型的 Intent 消息不会出现重叠,BroadcastIntent 消息只会发送给 BroadcastReceiver ,而绝不可能发送给 Activity 或 Server 。有 startActivity() 传递的消息也只可能发送给Activity,由 startService() 传递的 Intent 只可能发送给 Service 。

你可能感兴趣的:(Android)