Android四大基本组件详解-Activity,BroadcastReceiver,Service及ContentProvicer
文章目录
- 一,活动(Activity)
-
- 1.简介
- 2.任务栈
- 3.Activity的4种状态
- 4. 7种生命周期方法
- 5.Activity的四种启动模式
-
- (1)Standard 标准模式(默认启动模式)
- (2)SingleTop 栈顶模式(栈顶复用模式)
- (3)SingleTask 单任务模式(栈内复用模式)
- (4)SingleInstance 单实例模式(全局唯一模式)
- 6.谈谈onSaveInstanceState()方法?何时调用
- 二,广播消息接收器(BroadcastReceiver)
-
- 1.概念
- 2.举个栗子
- 3.重要性及适用场景
- 4.无序广播与有序广播代码实现
-
- (1)发送自定义的无序广播
- (2)发送自定义的有序广播
- 5.有序广播和无序广播的区别:
- 三,服务(Service)
-
- 1.概念
- 2.启动Service(两种方式)
- 四,内容提供者(ContentProvicer)
一,活动(Activity)
1.简介
应用程序中,一个Activity通常就是一个单独的屏幕。每个Activity都被实现为一个独立的类,并且从Activity基类继承而来, Activity类会提供视图控制组件的用户接口,并对事件作出响应。
2.任务栈
Android应用可能含有多个Activity,需要借助Activity活动栈机制来管理这些Activity之间的先后次序关系。
①任务栈用来存放用户开启的Activity。
②在应用程序创建之初,系统会默认分配给其一个任务栈(默认一个),并存储根Activity。
③同一个Task Stack,只要不在栈顶,就是onStop状态
④任务栈的id自增长型,是Integer类型。
⑤新创建Activity会被压入栈顶。点击back会将栈顶Activity弹出,并产生新的栈顶元素作为显示界面(onResume状态)。
⑥当Task最后一个Activity被销毁时,对应的应用程序被关闭,清除Task栈,但是还会保留应用程序进程,再次点击进入应用会创建新的Task栈。
3.Activity的4种状态
状态名 | 解释 | 举例 |
---|---|---|
活动状态 | 当前Activity在Activity活动栈中处于最上层,完全能被用户看到,并能够与用户进行交互。 | 正在运行的屏幕 |
暂停状态 | 当前Activity在界面上被部分遮挡(以对话框形式展示),不再处于用户界面的最上层,不能够与用户进行交互。 | 启动一个新的Activity |
停止状态 | Activity在界面上完全不能被用户看到,也就是说这个Activity被其他Activity全部遮挡。 | 用户按下“Home”键时 |
非活动状态 | 不在以上三种状态中的Activity,处于非活动状态。 | 被销毁的Activity |
4. 7种生命周期方法
5.Activity的四种启动模式
(1)Standard 标准模式(默认启动模式)
该模式可以被设定,不在manifest设定时候,Activity的默认模式就是standard。在该模式下,启动的Activity会依照启动顺序被依次压入Task中:
(2)SingleTop 栈顶模式(栈顶复用模式)
在该模式下,如果栈顶Activity为我们要新建的Activity(目标Activity),那么就不会重复创建新的Activity。
代码示例:
<activity android:name=".TwoActivity" android:launchMode="singleTop"> <intent-filter> <action android:name="ONETEXT_TWOACTIVITY" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter></activity>
(3)SingleTask 单任务模式(栈内复用模式)
与singleTop模式相似,只不过singleTop模式是只是针对栈顶的元素,而singleTask模式下,如果task栈内存在目标Activity实例,则:
①将task内的对应Activity实例之上的所有Activity弹出栈。
②将对应Activity置于栈顶,获得焦点。
(4)SingleInstance 单实例模式(全局唯一模式)
在该模式下,我们会为目标Activity分配一个新的affinity,并创建一个新的Task栈,将目标Activity放入新的Task,并让目标Activity获得焦点。新的Task有且只有这一个Activity实例。 如果已经创建过目标Activity实例,则不会创建新的Task,而是将以前创建过的Activity唤醒
• 小试牛刀:
问题:A、B、C、D分别是四种Activity的启动模式,那么A- >B->C->D->A->B->C->D分别启动,最后的activity栈是怎么样的?
答案:两个栈,前台栈是只有D,后台栈从底至上是A、B、C。
6.谈谈onSaveInstanceState()方法?何时调用
当Activity意外销毁时再重建时会调用此方法,比如横竖屏切换会导致重建Activity,onSaveInstanceState()方法的调用在onStop()之前,用于保存当前Activity的状态,当Activity被重新创建后,会调用onRestoreInstanceState()来恢复Activity的状态,onRestoreInstanceState()的调用在onStart()之前。
onSaveInstanceState()执行场景:
- 当用户按下HOME键时
- 长按HOME键,选择运行其他的程序时
- 锁屏时
- 从activity A中启动一个新的activity时
- 屏幕方向切换时
二,广播消息接收器(BroadcastReceiver)
1.概念
BroadcastReceiver是Android系统中常用的一种机制,用户让应用对一个外部的事件作出响应。
2.举个栗子
例如:①开机的时候,系统会进行一个全局广播,消息是按开机了,这时候有广播接收者接到了这个消息,就会相应启动一些程序或服务,实现开机启动。
②还有就是你的网络出了问题,比如网络断开了,链接到wifi之类,或者还有电量改变,收发短信都会发出广播,这时候有对应的程序来反应。
3.重要性及适用场景
可能觉得BroadcastReceiver没有大的用处,可能因为你现在的程序还没有用到关于系统事件所对应的反应,但这不代表BroadcastReceiver是不重要的。
平时在开发过程中遇到的单进程多线程通信的场景比较多,所以这种情况下使用BroadcastReceiver并不是最佳选择,很多人会自己实现一套Observer 或者使用EventBus等第三方库来完成该功能,不可否认,他们在这种场合下不论是效率还是灵活性方面都更具优势。
但是,BroadcastReceiver既然能够在Android四大组件中占有一席之地,自然也有它独有的优势,①是系统相关事件的监听,比如开机启动,网络连接,电量变化等。②是多进程通信,这些是Observer 或者EventBus很难办到的。
所以BroadcastReceiver的使用需要看具体的使用场景,像单进程多线程这种场景,就不建议用BroadcastReceiver了,有种杀鸡用牛刀的感觉,使用Observer 或者EventBus更适合;但是对于需要监听系统广播事件的场合,例如现在很多进程保活机制里面就用到了一些系统广播的监听,就正是BroadcastReceiver大展拳脚的时候了。
4.无序广播与有序广播代码实现
(1)发送自定义的无序广播
①发送广播
public void startBroadcast(View view){ //开启广播 //创建一个意图对象 Intent intent = new Intent(); //指定发送广播的频道 intent.setAction("com.example.BROADCAST"); //发送广播的数据 intent.putExtra("key", "发送无序广播,顺便传递的数据"); //发送 sendBroadcast(intent); }
②接收广播
新建一个类,继承BroadcastReceiver(类比于购买了一个收音机)
public class UnorderedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); String data = intent.getStringExtra("key"); System.out.println("接受到了广播,action:"+ action +",data:"+data); //接受到了广播,action:com.example.BROADCAST,data:发送无序广播,顺便传递的数据 }}
③在清单文件中进行注册
<receiver android:name="com.example.selfreceiver.UnorderedReceiver"><intent-filter> <action android:name="com.example.BROADCAST"/> </intent-filter></receiver>
④运行结果
(2)发送自定义的有序广播
1)发送广播
// 发送有序广播 public void sendOrderedBroad(View view) { Intent intent = new Intent(); intent.setAction("com.example.ORDERED"); // 发送无序广播 sendOrderedBroadcast(intent,//意图动作,指定action动作 null, //receiverPermission,接收这条广播具备什么权限 new FinalReceiver(),//resultReceiver,最终的广播接受者,广播一定会传给他 null, //scheduler,handler对象处理广播的分发 0,//initialCode,初始代码 "每人发10斤大米,不得有误!", //initialData,初始数据 null//initialExtras,额外的数据,如果觉得初始数据不够,可以通过bundle来指定其他数据 ); }
在上面的代码中,广播发送者发送了一条广播:“每人发10斤大米,不得有误!”
2)接收广播
新建一个类, 继承BroadcastReceiver,并在清单文件中进行注册
以下是所有的广播接收者在清单文件中的注册
权限从-1000 至 1000
①权限高的广播接收者可以修改广播,甚至可以终止广播
权限高的广播接收者1:
public class ShengReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //获取广播的数据 String data = getResultData(); //修改 setResultData("中央下达福利,每人5斤大米"); System.out.println("省政府收到指示, data : "+data); }}
在这里, 这个接收者修改广播为: “中央下达福利,每人5斤大米”
权限低的广播接收者
public class PeopleReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //获取广播的数据 String data = getResultData(); System.out.println("老百姓收到福利,感谢党, data : "+data); }}
这样,在控制台打印出来的信息为:
权限低的接收者 接收到的广播就是修改后的了
②终止广播
权限高的广播接收者:
public class ShengReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //获取广播的数据 String data = getResultData(); //也可以终止广播,权限小的接收者就接收不到广播了 abortBroadcast(); System.out.println("省政府收到指示, data : "+data); }}
控制台打印:
权限小的就接收不到广播了…
③resultReceiver
可以在广播发送者的应用中建一个resultReceiver, 用于接收最终到达的广播,
无论广播是否终止,都会被resultReceiver接收
public class FinalReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String resultData = getResultData(); System.out.println("人民收到的最终福利是: "+ resultData); }}
控制台打印信息:
(终止广播后):
(修改广播后):
5.有序广播和无序广播的区别:
(1)无序广播:发送方发出后,几乎同时到达多个广播接收者处,某个接收者不能接收到广播后进行一番处理后传给下一个接收者,并且无法终止广播继续传播;
Context.sendBroadcast(intent);
(2)有序广播:广播接收者需要提前设置优先级,优先级高的先接收到广播,优先级数值为-1000~1000,在AndroidManifest.xml的设置;比如存在3个广播接收者A、B、C,优先级A>B>C,因此A最先收到广播,当A收到广播后,可以向广播中添加一些数据给下一个接收者(intent.putExtra()),或者终止广播(abortBroadcast());
Context.sendOrderedBroadcast(intent);
三,服务(Service)
1.概念
一个服务是具有一个较长生命周期且没有用户界面的程序。例如:一个正在从播放列表中播放歌曲的媒体播放器。
2.启动Service(两种方式)
(1)使用startService()方法启动Service,调用者与Service之间没有关系,即使调用者退出了,Service仍然运行。Service不会自动销毁,需要外部调用stopService()方法或在Service内部调用stopSelf()方法,此时Service的onDestroy()方法被调用。
(2)使用bindService()方法启动Service,调用者与Service绑定在了一起,调用者一旦销毁,Service也就终止了,调用者需要解绑时可调用unBindService()方法。Service被解绑或调用者销毁时,Service经历onUnbind() > onDestroy()的过程。
四,内容提供者(ContentProvicer)
– 应用程序能够将它们的数据保存到文件、SQLite数据库中,甚至是任何有效的设备中。当需要将当前应用数据与其它应用共享时,ContentProvider类实现了一组标准方法,从而能够让其它的应用保存或读取此ContentProvider处理的各种数据类型。