-
Android
四大基本组件介绍与生命周期
Android
四大基本组件分别是
A
ctivity
,
Service
服务
,Content Provider
内容提供者,
BroadcastReceiver
广播接收器。
一
:
了解四大基本组件
Activity :
应用程序中,一个
Activity
通常就是一个单独的屏幕
,它上面可以显示一些控件也可以监
听并处理用户的事件做出响应。
Activity
之间通过
In
tent
进行通信。在
Intent
的描述结构中,有两个最重要的部分:动
作和动作对应的数据。
典型的动作类型有:
M AIN
(
p>
activity
的门户)、
VIEW
p>
、
PICK
、
ED
IT
等。而动作对应的
数据则以
URI <
/p>
的形式进行表示。例如:要查看一个人的联系方式,你需要创建一个动作类
型为
VIEW
的
inten
t
,以及一个表示这个人的
URI
。<
/p>
与之有关系的一个类叫
IntentF
ilter
。相对于
intent
是一个有效的做某事的请求,一个
intentfilter
则用于描述一个
activity
(或
者
IntentReceiver
)能够操作哪些
intent
。一
个
act
ivity
如果要显示一个人的联系方式时,需要声明一个
I
ntentFilter
,这个
IntentFilter
要知道怎么去处理
VIEW
动作和表
示一个人的
URI
。
IntentFi
lter
需要在
中定义。
通过解析各种
intent
,
< br>从一个屏幕导航到另一个屏幕是很
简单的。当向前导航时,
activity
将会调用
startActivity(Intent myI
ntent)
方法。然后,
系统会在所有安装的应用程序中定义
的
IntentFilter
中查找,找到最匹配
myIntent
的
Intent
对应的
activity
。新的
activity
接收到
myIntent
的通知后,开始运行。当
startActivity
方法被调用将触发解析
myIntent
的动作,这个机制提供了两个关键好处:
A
、
Activities
能够重复利用从其它组件中以
Intent
的形式产生的一个请求;
B
、
Activities
可以在任何时候被一个具有相同
IntentFilter
的新的
Activity
取代。
AndroidManife
st
文件中含有如下过滤器的
Activity
组件为默认启动类当程序启动时系统
自动调用它
<
intent-
filter
>
<
action
android:name
=
/>
<
category
android:name
=
/>
intent-
filter
>
Broadcast
Receive
广播接收器
:
你的应用可以使用它对外部事件进行过滤只对感兴趣的外部事件
(
p>
如当电话呼入时,或者数
据网络可用时
)<
/p>
进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个
activity
或
serice
< br>来响应它们收到的信息,或者用
NotificationManager
p>
来通知用户。
通知可以用很多种方式来吸引用户的注意力
──
闪动背灯、震动、播放声音等。一般来说是
在
状态栏上放一个持久的图标,用户可以打开它并获取消息。
广播类型:
普通广播
,
通过
oadcast(Intent
myIntent)
发送的
有序广播
,
通过
deredBroadcast
(intent, receiverPermission)
发送
的,
该方法第
2
个参数决定该广播
的级别,
级别数值是在
-1000
到
1000
之间
,
值越大
,
发送的优先级越高;广播接收者接收广播时的级别级别(可通过
intentfilte
r
中的
priority
进行设置设为
2147483647
时优先级最高),同级别接收的先后是随
机的,
再到级别低
的收到广播,
p>
高级别的或同级别先接收到广播的可以通过
abortBroadc
ast()
方法截断广播
使其他的接收者无法收到该广播,还有
其他构造函数
异步广播
,
通过
ickyBroadcast(Intent myIntent)<
/p>
发送的,还有
sendStickyOrderedBroadc
ast(intent, resultReceiver, scheduler,
initialCode,
initialData, initialExtras
)
方法,该方法具有有序广播的特性也有异步广播的特性;发送
异步广播要:
注意:发送广播时的 <
br>ctivity()
android:name=
/><
/p>
权限,
接收并处理完
Intent
后,广播依然存在,直到你调用
removeStickyBroad
cast(intent)
主动把它去掉
intent
参数与
启动起来的
Intent
不同
,
前者
可以被多个订
阅它的广播接收器调用
,
后者只能被一个
(Activity
或
service)
调用
监听广播
Intent
p>
步骤
:
1>
写一个继承
BroadCastReceiver
的类
,
重写
onRecei
ve()
方法
,
广播接收器
仅在它执行这个方法时处于活跃状态。当
onReceive()
返回后,它即为失活状态
,
注意
:
为
了保证用户交互过程的流畅
,
一些费时的操作要放到线程里
,
如
类名
SMSBroadcastReceiver
2>
注册该广播接收者
,
注册有两种方法程
序动态注册和
AndroidManifest
文件中
进行静态注册(可理解为系统中注册)如下:
静态注册
,
注册的广播,下面的
priority
表示接收广播的级别
2147483647
为最高
优先级
<
receiver
android:name
=
>
<
intent-filter
android:priority
=
>
<
action
android:name
=
/>
intent-
filter
>
receiver
>
动态注册,一般在
Activity
可交互时
onResume()
p>
内注册
BroadcastReceiver
IntentFilter
intentFilter=
new
IntentFilter(
registerReceiver(mBatteryI
nfoReceiver ,intentFilter);
//
反注册
unregisterReceiver(receiver);
注意:
1.
生命周期只有十秒左右,如果在
onReceive()
内做超过十秒内的事情,就会报
p>
ANR(Application No Response)
程
序无响应的错误信息,
如果需要完成一项比较耗时的
工作
,
应该通过发送
Intent
给
Service,
由
Service
来完成
.
这里不能使用子线程来
解决
,
因为
BroadcastReceiver
的生命周期很短
,
子线程可能还没有结束
BroadcastReceiver
就先结束了
.BroadcastReceiver
一旦结束
,
此时
BroadcastReceiver
的所在进程很容易在系统需要内存时被优先杀死
,
因为它属于空进
程
(
没有任何活动组件的进程
).
如果它的宿主进程被杀死
,
那么正在工作的子线程也
会被杀死
.
所以采用子线程来解决是不可靠的
2.
动态注册广播接收器还有一个特点,就是当用来注册的<
/p>
Activity
关掉后,广播也就失效
了。
静态注册无需担忧广播接收器是否被关闭
,
只要设备是开启状态
,
广播接收器也是打开着
的。也就是说哪怕
app
本身未启动
,
该
app
订阅的广播在
触发时也会对它起作用
系统常见广播
Intent,
如开机启动、电池电量变化、时间改变等广播
Service
服务
:
一个
Service
是一段长生命周
期的,没有用户界面的程序,可以用来开发如监控类程序。
比
较好的一个例子就是一个正在从播放列表中播放歌曲的媒体播放器。
在一个媒体播放器的
应用中,应该会有多个
activity
,让使用者可以选择歌曲并播放歌曲。然而,音乐重放这个
功能并没有对应的
activity
,
因为使用者当然会认为在导
航到其它屏幕时音乐应该还在播放
的。
在这个例子中,
媒体播放器这个
activity
会使用
p>
ervice()
来启动一个
servic
e
,从而可以在后台保持音乐的播放。同时,系统也将保持这个
service
一直执行,
直到这个
service
运行结束。另外,我们还可以通过使用
rvice()
方法,
连接到一个
service
上
(如果这个
service
还没有运行将启动它)
。
当连接到一个
service
之后,我们还可以
service
提
供的接口与它进行通讯。拿媒体播放器这个例子来说,我们
还可以进行暂停、重播等操作
。
Service
使用步骤如下
1>
继承
service
类
2>
配置清单文件中
节点里对服务进行配置
<
br>, <
br>服务首次启动系统先调用服务的
<
br>个方法
<
br>平台提供了 ,
服务不能自己运行
,
需要通过
ervice()
或
rvice()
启动服务
通过
startService()
方法启动
的服务于调用者没有关系
,
即使调用者关闭了
服务仍然运行
想停止服务要调用
rvice(),
此时系统会调用
onDestory(),
使用此方法启
动时
,
onCreate()-->onStart()
,
如果服务已经启动再次
调用只会触发
onStart()
方法
使用
bindService()
启动的服务与调用者绑定
,
只要调用者关闭服务就终止
,
使用此方法启
动时
,
服务首次启动系
统先调用服务的
onCreate()-->onBind(),
如果服务已经启动再次调
用不会再触发这
2
,
调用者退出时系统会调用服务的
onUnbind()-->onDestory(),
想主动解除绑定可使用
Service(),
系统依次调用
o
nUnbind()-->onDestory();
Content
Provider
内容提供者
:
android
Content Provider
使一个应
用程序的指定数据集提供给其他应用程
序。这些数据可以存储在文件系统中、在一个
p>
SQLite
数据库、或以任何其他合理的方式
其他应用可以通过
ContentResolver<
/p>
类
(
见
Cont
entProviderAccessApp
例子
)
从该内容
提供者中获取或存入数据
.(
相当于在应用外包了一层壳
),
只有需要在多个
应用程序间共享数据是才需要内容提供者。
例如,
通讯录数据被
多个应用程
序使用,且必须存储在一个内容提供者中
它的好处
:
统一数据访问方式。
android
系统自带的内容提供者
(
顶级的表示数据库名
,
非
顶级的都是表名
)
这些内容提供者
在<
/p>
SDK
文档的
er Java
包中都有介绍。见:
/reference/android/provi
der/package-summary.
html
├
────Browser
├
────CallLog
├
────Contacts
│
├
────Groups
│
├
────People
│
├
────Phones
│
└────Photos
├
────Im
ages
│
└────Thumbnails
├
────MediaStore
│
├
────Albums
│
├
────Artists
│
├
────Audio
│
├
────Genres
│
└────Playlists
├
────Settings
└────Video
CallLog
:地址和接收到的电话信息
:存储电话号码
:系统设置和偏好设置
使用
Content
Provider
对外共享数据的步骤
1>
继承
ContentProvider
< br>类并根据需求重写以下方法
:
public
boolean
onCreate();
//
处理初始化操作
/**
*
插入数据到内容提供者
(
允许其他
应用向你的应用中插入数据时重
写
)
*
@param
uri
*
@param
initialValues
插入的数据
*
@return
*/
public
Uri insert(Uri uri,
ContentValues initialValues);
/**
*
从内容提供者中删除数据
(
允许其
他应用删除你应用的数据时重写
)
*
@param
uri
*
@param
selection
条件语句
*
@param
selectionArgs
参数
*
@return
*/
public
int
delete(Uri uri, String
selection, String[]
selectionArgs);
/**
*
更新内容提供者已存在的数据
(
允许其他应用更新你应用的数据时重
写
)
*
@param
uri
*
@param
values
更新的数据
*
@param
selection
条件语句
*
@param
selectionArgs
参数
*
@return
*/
public
int
update(Uri uri,
ContentValues values, String
selection,
String[]
selectionArgs);
/**
*
返回数
据给调用者
(
允许其他应用从你的应用中获取数据时重写
)
*
@param
uri
*
@param
projection
列名
*
@param
selection
条件语句
*
@param
selectionArgs
参数
*
@param
sortOrder
排序
*
@return
*/
public
Cursor query(Uri uri,
String[] projection, String
selection,
String[]
selectionArgs, String sortOrder)
/**
*
用于返回当前
U
ri
所代表数据的
MIME
类型
*
如果操作的数据为集
合类型
(
多条数据
),
那么返回的类型字符串应该
为
/
开头
*
例如要
得到所有
person
记录的
Uri<
/p>
为
content://provider/person,
*
那
么返回的
MIME
类型字符串应该为
<
/p>
*
如果操作的数据为单一数据
,
那么返回的类型字符串应该为
/
开头
*
例如
要得到
id
为
10
的
person
记录的
Uri
p>
为
content://provider/person/10,
*
那
么返回的
MIME
类型字符串应该为
<
/p>
*
@param
uri
*/
public
String getType(Uri
uri)
这些方法中的
Uri
p>
参数
,
得到后需要进行解析然后做对应处理
,Uri
表示要操作的数据
,
包含两
部分信息
:
1.
需要操作的
contentpro
vider
2.
对<
/p>
contentprovider
中的什么数据进行操作
,
一个
Uri
格式
p>
:
结构
头
://a
uthorities(
域名
)/
路径
(
要操作的数据
,
根据业务而定
)
content://provider/person/10
说明
:contentprovider
的结构头已经由
p>
android
规定为
content:/
/
authorities
用于唯一标识这个
contentprovider
程序
,
外部调用者可以根据这个找到他
路径表示我们要操
作的数据
,
路径的构建根据业务而定
.
路径格式如
下
:
要操作
person<
/p>
表行号为
10
的记录
,
可以这样构建
/person/10
要操作
person<
/p>
表的所有记录
,
可以这样构建
/person
2>
在
中使用
对
ContentProvider
进行配置注册
(
内
容提供者注册它自己就像网站注册域名
< br>),ContentProvider
采用
author
itie(
原意授权
,
可
理解为域名
)
作为唯一标识
,
方便其他应用能找到
<
application
android:icon
=
android:label
=
>
<
provider
android:name
=
android:authorities
=
...
ap
plication
>
关于四大基本组件的一个总结:
1>
4
大组件的注册
4
大基本组件都需要注册才能使用
,
每个
Activity
、
servi
ce
、
Content Provider
内容提供
者都需要在
AndroidManifest
p>
文件中进行配置
AndroidManifest
< br>文件中未进行声明的
activity
、服务以及内容提
供者将不为系统所见,从而也就不可用,而
BroadcastReceive
广播接收者的注册分静态注册(在
AndroidManifest
p>
文件中进行配置)和通过代码动态创
建并以调用
erReceiver()
的方式注册至系统。需要注意的是在
AndroidManifest
文件中进行配置的广播接收者会随系统的启动而一
直处于活跃状态
,
只
要接收到感兴趣的
广播就会触发(即使程序未运行)
AndroidManif
est
文件中进行注册格式如下:
元素的
name
属性指定了实现了这个
activity
的
Activity
的子类。
icon
和
label
属性指向了包含展示给用户的此
activity
的图标和标签的资源文件。
元素用于声明服务
元素用于声明广播接收器
元素用于声明内容提供者
2>
4
大组件的激活
?
容提供者的激活:当接收到
ContentResolver
发出的请求后,内容提供者被激活。而
其它三种组件
──activity
、服务和广播接收器被一种叫做
intent
的异步消息所激活
?
Activity
的激活通过传递一个
Intent
对象至
ctivity()
或
< br>ctivityForResult()
以载入(或指定新工作给)一个
activity
。相应的
activity
可以通过调用
getIntent()
方法来查看激活它的
intent
。如果它期望它所启动的<
/p>
那个
activity
返回一个结果,
它会以调用
startActivityForResult()
来取代
startActivity()
。比如说,如果它启
动了另外一个
Activity
以使用户挑选一张照片,它也
许想知道哪张照片被选中了。
结果将会被封装在一个
Intent
对象中,
并传递给发出调用的
p>
activity
的
onActivityResult()
方法。
?
服务的激活可以通过传递一个
Intent
< br>对象至
ervice()
或
rv
ice()
前者
Android
调用
服务的
onStart()
方法并将
I
ntent
对象传递
给它,后者
Android
调用服务的
onBind()
方法将这
个
Intent
对象传递给它
?
发送广播可以通过传递一个
Intent
对象至给
oadcast()
、
deredBroadcast(
)
或
ickyBroadcast()Android
会
调用所有对此广播有兴趣的广播接收器的
o
nReceive()
方法,将
intent
传递给它们
3>
四大组件的关闭
内容提供者仅在响应
ContentResolver
提出请求的时候激活。
而一个广播接收器仅在响应
广播信息的时候激活。所以,没有必要去显式的关闭这些组件。
< br>Activity
关闭:可以通过调用它的
finish
()
方法来关闭一个
activity
服务关闭:对于通过
startService()
方法启动
的服务要调用
rvice()
方法
关闭
服务,使用
bindService()
方法启动的服务要调用
Service
()
方法关
闭服务
< br>二
:
四大组件的生命周期
介绍生命周期之前,先提一下任务的概念
任务其实就是
activity
的栈
它由一个或多个
Activity
组成的共同完成一个完整的用
户体
验,
换句话说任务就是
”
应用程序
”
(可以是一个也可以是多
个,比如假设你想让用户看
到某个地方的街道地图。
而已经存在
一个具有此功能的
activity
了,那么你的
activity
所<
/p>
需要做的工作就是把请求信息放到一个
Intent
对象里面,并把它传递给
startActivity()
。
于是地图浏览器就会显示那个地图。
而当用户按下<
/p>
BACK
键的时候,
你的
activity <
/p>
又会再
一次的显示在屏幕上,此时任务是由
2
个应用程序中的相关
activity
组成的)栈底的是启
动整个任务的
Activity
,
栈顶的是当前运行的用户可以交互的
Act
ivity
,
当一个
activity
启
动另外一个的时候,新的
activ
ity
就被压入栈,并成为当前运行的
activity
p>
。而前一个
activity
仍保持在栈之中。
当用户按下
BACK
键的时候,
当前
activity <
/p>
出栈,
而前一个恢
复为当前运行的
activity
。栈中保存的其实是对象,栈中的
< br>Activity
永远不会重排,只会
-
-
-
-
-
-
-
-
-
上一篇:obsity 2
下一篇:颈部解剖位置的定位[1]