Android四大组件之一——Activity服务
intent是activity、broadcast和service的三者间信使
五种状态
状态 | 说明 |
---|---|
1. 启动Active(点击) | 可见,未获得焦点,瞬间动作,立马进入Running |
2. 运行Running(当前手机的屏幕时运行的APP) | 可见,焦点停留在本状态的Activity,位于屏幕的最前端 |
3. 暂停Paused(当前APP中出现其他句柄的控件,并且一定需要点击才可以返回) | 可见,失去焦点(不响应) |
4. 停止Stopped(HOME键切换为其他应用) | 不可见,失去焦点,内存仍被保存在本Activity中未清理 |
5. 销毁Dead(清理应用的时候) | 把Activity中的内存清空,并且把Activity清除返回栈 |
七个方法
方法 | 说明 |
---|---|
1.onCreate() | 当Activity可见未获得用户焦点不能交互时系统会调用 |
2.onStart() | 当Activity已经停止然后重新被启动时系统会调用 |
3.onResume() | 在Activity获取得到焦点开始可以与用户进行交互的时候调用onSaveInstanceState() 用来保存Activity被杀之前的状态,当此Activity再次被实例化时会通过onCreate(Bundle savedInstanceState) 将已经保存的临时状态数据传入当出现按下HOME键、按下电源按键、关闭屏幕、横竖屏切换等情况时,仅重写 onSaveInstanceState() 来记录activity的临时状态,而使用onPause() 来存储持久数据。 |
4.onPause() | 当Activity被新的Activity完全覆盖不可见时被系统调用 |
5.onStop() | 当Activity(用户调用finish() 或系统由于内存不足)被系统销毁杀掉时系统调用,(整个生命周期只调用1次)用来释放onCreate() 方法中创建的资源,如结束线程等 |
6.onDestroy() | 在Activity要销毁时调用 |
7.onRestart() | 在Activity从Stopped再次获取得到焦点启动时调用 |
Android四大组件之二——BroadcastReceiver广播接收器
三种广播
广播形式 | 说明 |
---|---|
1. 普通广播 | 通过Context.sendBroadcast(Intent myIntent) 发送 |
2. 有序广播 | 通过Context.sendOrderedBroadcast(intent, receiverPermission) 发送 |
3. 异步广播 | 通过Context.sendStickyBroadcast(Intent myIntent) 发送或者 sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, initialData, initialExtras) ,该方法具有有序广播的特性也有异步广播的特性;发送异步广播要: <uses-permission android:name=*"android.permission.BROADCAST_STICKY"* /> 权限,接收并处理完Intent后,广播依然存在,直到你调用removeStickyBroadcast(intent) 主动把它去掉 |
监听广播Intent步骤
- 写一个继承
BroadcastReceiver
的类,重写onReceive()
方法,广播接收器仅在它执行这个方法时处于活跃状态,当onReceive()
返回后,它即为失活状态。 - 注册该广播接收者,注册有两种方法:
AndroidManifest.xml
文件中进行静态注册(可理解为系统中注册)和程序动态注册,如下:
- 静态注册,注册的广播,下面的priority表示接收广播的级别"2147483647"为最高优先级
<receiver android:name=".SMSBroadcastReceiver" > <intent-filter android:priority = "2147483647" > <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>
- 动态注册,一般在Activity可交互时
onResume()
内注册BroadcastReceiver
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); registerReceiver(mBatteryInfoReceiver, intentFilter);// 反注册unregisterReceiver(receiver);
-
生命周期:
只有十秒左右,从回调
onReceive()
方法开始到该方法返回结果后结束,如果在onReceive()
内做超过十秒内的事情,就会报ANR(Application No Response) 程序无响应的错误信息。如果需要完成一项比较耗时的工作 , 应该通过发送
Intent
给Service
,由Service
来完成。而不能用子线程来解决,因为
BroadcastReceiver
一旦结束,此时BroadcastReceiver
的所在进程很容易在系统需要内存时被优先杀死,因为它属于空进程 ( 没有任何活动组件的进程 )。如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死 。所以采用子线程来解决是不可靠的。 -
动态注册广播,当用来注册的Activity关掉后,广播也就失效了;而静态注册广播只要设备是开启状态,广播接收器也是打开的,在触发时也会对它起作用。
Android四大组件之三——Service服务
一个Service
是一段长生命周期的,没有用户界面的程序,可以用来开发如监控类程序,建议将一些(耗时)的后台操作做成Service
的形式。
Service使用步骤如下:
-
继承Service类
-
AndroidManifast.xml
配置清单文件中<application>
节点里对服务进行配置<service name=".SMSService"/>
启动服务 (整个生命周期只调用1次这个方法,通常用于初始化设置) | Context.startService() | Context.bindService() |
---|---|---|
说明 | 服务首次启动系统先调用服务的onCreate() –>onStart() ,如果服务已经启动再次调用只会触发onStart() 方法 | 与调用者绑定,只要调用者关闭服务就终止,使用此方法启动时,服务首次启动系统先调用服务的onCreate() –>onBind() ,如果服务已经启动再次调用不会再触发这2个方法,调用者退出时系统会调用服务的onUnbind() –>onDestory() ,想主动解除绑定可使用Contex.unbindService() ,系统依次调用onUnbind() –>onDestory() |
停止Service被系统调用 (整个生命周期只调用1次,用来释放 onCreate() 方法中创建的资源) | stopService() | unbindService() |
Android四大组件之四——Content Provider内容提供者
android平台提供了Content Provider
使一个应用程序的指定数据集提供给其他应用程序,这些数据可以存储在文件系统、SQLite数据库、或以任何其他合理的方式。
只有需要在多个应用程序间共享数据是才需要内容提供者。例如,通讯录数据被多个应用程序使用,且必须存储在一个内容提供者中。
好处:统一数据访问方式
总结
1. 四大基本组件的注册
四大基本组件都需要注册才能使用:
每个Activity活动
、service服务
、Content Provider内容提供者
都需要在AndroidManifest
文件中进行配置,AndroidManifest
文件中未进行声明的activity、service以及Content Provider
将不为系统所见,从而也就不可用;
而BroadcastReceiver
的注册分静态注册(在AndroidManifest
文件中进行配置)和通过代码动态创建并以调用,Context.registerReceiver()
的方式注册至系统。需要注意的是在AndroidManifest
文件中进行配置的广播接收者会随系统的启动而一直处于活跃状态,只要接收到感兴趣的广播就会触发(即使程序未运行)。
AndroidManifest
文件中进行注册格式如下:
<activity>
元素的name 属性指定了实现了这个activity 的Activity 的子类。icon 和label 属性指向了包含展示给用户的此activity 的图标和标签的资源文件。<service>
元素用于声明服务<receiver>
元素用于声明广播接收器<provider>
元素用于声明内容提供者
2. 四大组件的激活
-
Content Provider内容提供者:
当接收到
ContentResolver
发出的请求后,内容提供者被激活。 -
Activity活动:
传递一个Intent 对象至
Context.startActivity()
或Activity.startActivityForResult()
(如果期待启动的activity返回一个结果)以载入(或指定新工作给)一个activity
。相应的
activity
可以通过调用getIntent()
方法来查看激活它的intent
。 -
Service服务:
传递一个
Intent 对象
至Context.startService()
或Context.bindService()
,前者Android 调用服务的onStart()
方法并将Intent
对象传递给它,后者Android 调用服务的onBind()
方法将这个Intent
对象传递给它。 -
BroadcastReceiver广播接收器:
传递一个Intent 对象至给
Context.sendBroadcast()
、Context.sendOrderedBroadcast()
或Context.sendStickyBroadcast()
,Android 会调用所有对此广播有兴趣的广播接收器的onReceive()
方法,将intent
传递给它们。
3. 四大组件的关闭
-
Content Provider内容提供者:
仅在响应
ContentResolver
提出请求的时候激活,没必要显式地关闭 -
BroadcastReceiver广播接收器:
仅在响应广播信息的时候激活,没必要显式地关闭
-
Activity服务:
调用
finish()
-
Service服务:
对于通过
Context.startService()
方法启动的服务要调用Context.stopService()
方法关闭服务,使用Context.bindService()
方法启动的服务要调用Context.unbindService()
方法关闭服务
4. Dalvak虚拟机的内存回收规则
-
先回收与其他
Activity
或Service/Intent Receiver
无关的进程(即优先回收独立的Activity
)。因此建议将一些(耗时)的后台操作做成Service
形式。 -
不可见(处于Stopped状态的)
Activity
-
Service
进程(除非真的没有内存可用时会被销毁) -
非活动的可见的(Paused状态的)
Activity
-
当前正在运行(Active/Running状态的)
Activity