-
Android
基础之四大基本组件介绍与生命周期
Android
四大基本组件分别是
Activity
,
Service
服务
,Content Provider
内容提供者,
p>
BroadcastReceiver
广播接收器。
一
:
了解四大基本组件
p>
Activity :
应用程序中,一个
Activity
通常就是一个单独
的屏幕,它上面可以显示
一些控件也可以监听并处理用户的事件做出响应。
Activity
之间通过
Intent
进行通信。在
Intent
< br>的描述结构中,有两个最
重要的部分:动作和动作对应的数据。
< br>
典型的动作类型有:
M AIN
(
activity
的门户)
、
p>
VIEW
、
PICK
、
EDIT
等。
而动作对应的数据则以
URI <
/p>
的形式进行表示。例如:要查看一个人的
联系方式,你需要创建一
个动作类型为
VIEW
的
inten
t
,以及一个表示
这个人的
URI
p>
。
与之有关系的一个类叫
IntentFilter
。
相对于
< br>intent
是一个有效的做某事
的请求,
一个
intentfilter
则用于描述一个
activity
(
或者
IntentReceiver
)
能够操作哪些
p>
intent
。一个
activity <
/p>
如果要显示一个人的联系方式时,
需要声明一个
< br>IntentFilter
,这个
IntentFilt
er
要知道怎么去处理
VIEW
动
作和表示一个人的
URI
。
Inten
tFilter
需要在
中
定义。
通过解析各种
intent
,
从一个屏幕导航到另一个屏幕是很简单的。
当向前
导航时,
activity
将会调用
startActivity(Intent myI
ntent)
方法。
然
后,系统会在所
有安装的应用程序中定义的
IntentFilter
中查找,找到
最匹配
myIntent
的
Intent
对应的
activity
。新的
activity
接收到
myIntent
的通知后,
开始运行。
当
startActivi
ty
方法被调用将触发解析
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
或
seri
ce
来响应它们
收到的信息,或者用
NotificationManager
来通知用户。通知可以用很
多种方式来吸引用户的注意力
──
闪动背灯、震动、播
放声音等。一般
来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
p>
广播类型:
普
通广播
,
通过
oadcast(Int
ent myIntent)
发送的
有序广播
,
通过
deredBroad
cast(intent,
receiverPermission)
发送的,该方法第
2
个参数决定该广播的级别,级
p>
别数值是在
-1000
到
1000
之间
,
值越大
,
发送的优先级越高;广
播接收者接收广播时的级别级别(可通过
intentfilter
中的
priority
进行
设置设为
2147483647
时优先级最高),同级别接收的先后是随机的,
再到级别低的收到广播,高级别
的或同级别先接收到广播的可以通过
abortBroadcast()
方法截断广播使其他的接收者无法收到该广播,还有
其他构造函数
异步广播
,
通过
ickyBroadcast(Intent myIntent)
发送
的,
还有
sendStickyOrderedBroadca
st(intent, resultReceiver, scheduler,
initialCode, initialData, initialExtras
)
方法,该方法具有有序广播的特性
也有异步广播的特性;发送
异步广播要:
注意:发送广播时的 <
br>ctivity()
android:name=
/><
/p>
权限,
接收并处理完
Intent
后,广播依然存在,直到你调用
removeStickyBroad
cast(intent)
主动把它去掉
intent
参数与
启动起来的
Intent
不同
,
前者可以被多个订阅它的广播接收器调用<
/p>
,
后者只能被一个
(Activity<
/p>
或
service)
调用
监听广播
Intent
步骤
:
1>
写一
个继承
BroadCastReceiver
的类
,
重写
onReceive()
方法
,
广播接
收器仅在它执行这个
方法时处于活跃状态。当
onReceive()
返回后,它<
/p>
即为失活状态
,
注意
:
为了保证用户交互过程的流畅
,
一些费时的操作要
放到线程里
,
如类名
SMSBroadcastReceiver
2>
注册该广播接收者
,
注册
有两种方法程序动态注册和
AndroidManifest
文
件中进行静态注册(可理解为系统中注册)如下:
静态注册<
/p>
,
注册的广播,下面的
priority
表示接收广播的级别
21474836
47
为最高优先级
<
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()
内做超过十秒内的事情,
就会报
ANR(Application No Response) <
/p>
程序无响应的错误信息,如果
需要完成一项比较耗时的工作
,
应该通过发送
Intent
给
Service,
由
Service
来完成
.
这里不能使用子线程来解决
,
因为
BroadcastReceiver
的生命周期很短
,
子线程可能还没有结束
BroadcastReceiver
就先结束了
.BroadcastReceiver
一旦结束
,
此
时
BroadcastReceiver
的所在进程很容易在系
统需要内存时被优先杀
死
,
因为它属于空进程
(
没有任何活动组件的进程
).
如果它的宿主
进程被杀死
,
那么正在工作的子线程也会被杀死
.
所以采用子线程来
解决是不可靠的
2.
动态注册广播接收器还有一个特点,
就是当用来注册的
Activity
关掉
< br>后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭
,
只要
设备是开启状态
,
广播接
收器也是打开着的。也就是说哪怕
app
本身未
启动
,
该
app
订阅的广播在触发时也会对它起作用
系统常见广播
Intent,
如开机启动、电池电量变化、时间改变等广播<
/p>
Service
服务
:
一个
Service
是一段长生命周
期的,
没有用户界面的程序,
可以用来开
发如监控类程序。
比较好的一个例子就是一个正在从播放列
表中播放歌曲的媒体播放器。
在一个媒体播放器的应用中,应该会有多个
activity
,让使用者可以选
择歌曲并播放歌曲
。然而,音乐重放这个功能并没有对应的
activity
,<
/p>
因为使用者当然会认为在导航到其它屏幕时音乐应该还在播放的。
在这
个例子中,媒体播放器这个
activity
会使用
ervice()
来启
动一个
service
,从而可以在后台保持音乐的播放。
同时,系统也将保
持这个
service
一直执行,直到这个
service
运行结束。另外,我们还
可以通过使用
rvice()
方法,连接到一个
service
上(如
果这个
service
还没有运行将启动它)。当连接到一个
service
之后,
我们还可以
service <
/p>
提供的接口与它进行通讯。
拿媒体播放器这个例子
来说,我们还可以进行暂停、重播等操作。
Service
使用步骤如下
1>
继承
service
类
2>
配置清单文件中
节点里对服务进
行
配置
服务不能自己运行
,
需要通过
ervice()
或
rvice()
启动服务
通过
star
tService()
方法启动的服务于调用者没有关系
,
p>
即使调用者关闭
了
,
服务仍然运行想停止服务要调用
rvice(),
此时系统会
调用
onDestory(),
使用此
方法启动时
,
服务首次启动系统先调用服务的
< br>onCreate()-->onStart(),
如果服务已经启动再次调用只
会触发
onStart()
方法
p>
使用
bindService()
启动的服
务与调用者绑定
,
只要调用者关闭服务就终
止
,
使用此方法启动时
,
服务首次启动系统先调用服务的
onCreate()-->onBin
d(),
如果服务已经启动再次调用不会再触发这
2
个
方法
,
调用者退出时系
统会调用服务的
onUnbind()-->onDestory(),
想主
动解除绑定可使用
Service(),
系统依次调用
onUnbind()-->onDestory();<
/p>
Content
Provider
内容提供者
:
android
< br>平台提供了
Content Provider
使一个应
用程序的指定数据集提
供给其他应用程序。这些数据可以存储在文件系统中、在一个
p>
SQLite
数据库、或以任何其他合理的方式
,
其他应用可以通过
Conte
ntResolver
类
(
见
ContentProviderAccessApp
例子
)
从该内容提供者中获取或存入数据
.(
相当于在应用外包了一层壳
),
只有需要在多个应用程序间共享数据是才需要内容提供者。例如,通讯
录数据被
多个应用程序使用,且必须存储在一个内容提供者中
它的好处
:
统一数据访问方式。
android
系统自带的内容提供者
(
顶级的表示数据库名
,
非顶级的都是表
名
)
这些内容提供者在
S
DK
文档的
er Java
包中都有介
绍。
见:
/reference/android/provi
der/package-su
├────Browser
├────CallLog
├────Contacts
│
├────Groups
│
├────People
│
├────Phones
│
└────Photos
├────Images
│
└────Thumbnails
├────MediaStore
│
├────Albums
│
├────Artists
│
├────Audio
│
├────Genres
│
└────Playlists
├────Settings
└────Video
CallLo
g
:地址和接收到的电话信息
:存储电话号码
:系统设置和偏好设置
使用
Content
Provider
对外共享数据的步骤
1>
继承
ContentProvider
< br>类并根据需求重写以下方法
:
publicboolean
onCreate();
//
处理初始化操作
/**
*
p>
插入数据到内容提供者
(
允许其他应用向你
的应用中插入数
据时重写
)
*
@param
uri
*
@param
initialValues
插入的数据
*
@return
*/
public
Uri insert(Uri uri,
ContentValues initialValues);
/**
*
从内容
提供者中删除数据
(
允许其他应用删除你应用的数据
时重写
)
*
@param
uri
*
@param
selection
条件语句
*
@param
selectionArgs
参数
*
@return
*/
publicint
delete(Uri uri,
String selection, String[]
selectionArgs);
/**
*
更新内
容提供者已存在的数据
(
允许其他应用更新你应用的
数据时重写
)
*
@param
uri
*
@param
values
更新的数据
*
@param
selection
条件语句
*
@param
selectionArgs
参数
*
@return
*/
publicint
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)
/**
*
p>
用于返回当前
Uri
所代表数据的
MIME
类型
*
如果操作的数据为集合类型
(
多条
数据
),
那么返回的类型字
符串应该为
/
开头
*
例如要得到所有
person
记录
的
Uri
为
content://pr
ovider/person,
*
那么返回的
MIME
类型字符串应该为
*
如果操作的数据
为单一数据
,
那么返回的类型字符串应该为
/
开头
* <
/p>
例如要得到
id
为
10
的
person
记录的
Uri
为
content://provide
r/person/10,
*
那么返回的
MIME
类型字符串应该为
*
@param
uri
*/
public
String
getType(Uri uri)
这些方法中的
Uri
参数
,
得到后需要进行解析然后做对应处理
,Uri
表
示要
操作的数据
,
包含两部分信息
p>
:
1.
需要操作
的
contentprovider
2.
对
contentprovider
中的什么数据进行操作
,
一个
Uri
格式
:
结构
头
://authorities(
域名
)/
路径
(
要操作的数据
,
根据业务而定
)
content://provider/person/10
说明
:contentprovider
的结构头已经由
android
规定为
content://
authorities
用于唯一标识这个
contentprovider
程序
,
外部调用者可以根
据这个找到
他
路径表示我们要操作的数据
,
p>
路径的构建根据业务而定
.
路径格式如下<
/p>
:
要操作
p
erson
表行号为
10
的记录
,
可以这样构建
/person/10
要操作
person
表的所有记录
,
可以这样构建
/pe
rson
2>
在
中使用
对<
/p>
ContentProvider
进行配
置注册
(
内容提供者注册它自己就像网站注册域名
),ContentProvider
采
用
authoritie(
原意授权
,
可理解为域名
)
作为唯一标识
,
方便其他应用能找
到
<
application
android:icon
=
android:label
=
<
provider
android:name
=
android:authorities
=
>
...
application
>
关于四大基本组件的一个总结:
1> 4
大组件的注册
4
大基本组件都需要注册才能使用
,
每个
Activity
、
se
rvice
、
Content
Pro
vider
内容提供者都需要在
AndroidManifes
t
文件中进行配置
AndroidManifest
文件中未进行声明的
activity
、服务以及
内容提供者将
不为系统所见,从而也就不可用,而
Broadc
astReceive
广播接收者的
注册分静态注册(在
AndroidManifest
文件中进行配置)和通过代码动
p>
态创建并以调用
erReceiver()
的方式注册至系统。
需要注
意的是在
A
ndroidManifest
文件中进行配置的广播接收者会随系统的启
动而一直处于活跃状态
,
只要接收到感兴趣的广播就
会触发(即使程序
未运行)
Andr
oidManifest
文件中进行注册格式如下:
元素的
name
属性指定了实现了这个
activity
的
Activity
的
子类。
icon
和
label
属性指向了包含展示给用户的此
activity
的图标和
标签的资源文件。
元素用于声明服务
元素用于声明广播接收器
元素用于声明内容提供者
p>
2>
4
大组件的激活
?
容提供者的激活:
当接收到
ContentResol
ver
发出的请求后,
内容提
供者被
激活。而其它三种组件
──activity
、服务和广播接收
器被一种叫
做
intent
的异步消息所激活
?
Activity
的激活通过传递一个
Intent
对象至
ctivity()
或
< br>ctivityForResult()
以载入
(或指定
新工作给)
一个
activity
。<
/p>
相应的
activity
可以通过调用
getIntent()
方法来查看激活它的
intent
。
如果它期望它所启动的那个
activity
返回一个结果,
它会以调用
startActivityForResult()
来取代
startActivity()
。
< br>比如说,
如果它启动了另
外一个
Activity
以使用户挑选一张照片,
它也许想知道哪张
照片被选中
了。
结果将会被封装在一个
Intent
对象中,
并传递给发出调用的
< br>activity
的
onActivityResult()
方法。
?
服务的激活可以通过传递一个
Intent
< br>对象至
ervice()
或
rv
ice()
前者
Android
调用
服务的
onStart()
方法并将
I
ntent
对象传递给它,后者
Android
调用服务的
onBind()
方法将这个
Intent
对象传递给它
?
发送广播可以通过传递一个
Intent
对象至给
oadcast()
、
deredBroadcast(
)
或
ickyBroadcast()Android
会调用所有对此广播有兴趣的
广播接收器的
o
nReceive()
方法,将
intent
传递给它们
3>
四大组件的关闭
内容提供者仅在响应
ContentResolver
提出请求的时候激活。
而一个广
播接收器仅在
响应广播信息的时候激活。所以,没有必要去显式的关闭
这些组件。
Activity
关闭:可以通过调用它的
finish()
方法来关闭一个
activity
服务关闭:对于通过
startSe
rvice()
方法启动的服务要调用
rvice()
方法关闭服务,使用
bindService()
方法启动的服
务要调用
Service
()
方法关闭服务
二
:
四大组件的生命周期
介绍生命周期之前,先提一下任务的概念
任务其实就是
activity
的栈
它由一个或多个
Activity
组成的共同完成一
个完整的用户体验,换句话说任务就是
”
应用程序
”
(可以是一个也可
以是多个,比如假设你想让用户看到某个地方的街道地图。而已经存在
-
-
-
-
-
-
-
-
-
上一篇:(完整版)古典家居文案
下一篇:(整理)园林植物拉丁名1000种.