赞
踩
应用程序中,一个Activity通常就是一个单独的屏幕。每个Activity都被实现为一个独立的类,并且从Activity基类继承而来, Activity类会提供视图控制组件的用户接口,并对事件作出响应。
Android应用可能含有多个Activity,需要借助Activity活动栈机制来管理这些Activity之间的先后次序关系。
①任务栈用来存放用户开启的Activity。
②在应用程序创建之初,系统会默认分配给其一个任务栈(默认一个),并存储根Activity。
③同一个Task Stack,只要不在栈顶,就是onStop状态
④任务栈的id自增长型,是Integer类型。
⑤新创建Activity会被压入栈顶。点击back会将栈顶Activity弹出,并产生新的栈顶元素作为显示界面(onResume状态)。
⑥当Task最后一个Activity被销毁时,对应的应用程序被关闭,清除Task栈,但是还会保留应用程序进程,再次点击进入应用会创建新的Task栈。
状态名 | 解释 | 举例 |
---|---|---|
活动状态 | 当前Activity在Activity活动栈中处于最上层,完全能被用户看到,并能够与用户进行交互。 | 正在运行的屏幕 |
暂停状态 | 当前Activity在界面上被部分遮挡(以对话框形式展示),不再处于用户界面的最上层,不能够与用户进行交互。 | 启动一个新的Activity |
停止状态 | Activity在界面上完全不能被用户看到,也就是说这个Activity被其他Activity全部遮挡。 | 用户按下“Home”键时 |
非活动状态 | 不在以上三种状态中的Activity,处于非活动状态。 | 被销毁的Activity |
该模式可以被设定,不在manifest设定时候,Activity的默认模式就是standard。在该模式下,启动的Activity会依照启动顺序被依次压入Task中:
在该模式下,如果栈顶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>
与singleTop模式相似,只不过singleTop模式是只是针对栈顶的元素,而singleTask模式下,如果task栈内存在目标Activity实例,则:
①将task内的对应Activity实例之上的所有Activity弹出栈。
②将对应Activity置于栈顶,获得焦点。
在该模式下,我们会为目标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。
当Activity意外销毁时再重建时会调用此方法,比如横竖屏切换会导致重建Activity,onSaveInstanceState()方法的调用在onStop()之前,用于保存当前Activity的状态,当Activity被重新创建后,会调用onRestoreInstanceState()来恢复Activity的状态,onRestoreInstanceState()的调用在onStart()之前。
onSaveInstanceState()执行场景:
BroadcastReceiver是Android系统中常用的一种机制,用户让应用对一个外部的事件作出响应。
例如:①开机的时候,系统会进行一个全局广播,消息是按开机了,这时候有广播接收者接到了这个消息,就会相应启动一些程序或服务,实现开机启动。
②还有就是你的网络出了问题,比如网络断开了,链接到wifi之类,或者还有电量改变,收发短信都会发出广播,这时候有对应的程序来反应。
可能觉得BroadcastReceiver没有大的用处,可能因为你现在的程序还没有用到关于系统事件所对应的反应,但这不代表BroadcastReceiver是不重要的。
平时在开发过程中遇到的单进程多线程通信的场景比较多,所以这种情况下使用BroadcastReceiver并不是最佳选择,很多人会自己实现一套Observer 或者使用EventBus等第三方库来完成该功能,不可否认,他们在这种场合下不论是效率还是灵活性方面都更具优势。
但是,BroadcastReceiver既然能够在Android四大组件中占有一席之地,自然也有它独有的优势,①是系统相关事件的监听,比如开机启动,网络连接,电量变化等。②是多进程通信,这些是Observer 或者EventBus很难办到的。
所以BroadcastReceiver的使用需要看具体的使用场景,像单进程多线程这种场景,就不建议用BroadcastReceiver了,有种杀鸡用牛刀的感觉,使用Observer 或者EventBus更适合;但是对于需要监听系统广播事件的场合,例如现在很多进程保活机制里面就用到了一些系统广播的监听,就正是BroadcastReceiver大展拳脚的时候了。
①发送广播
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>
④运行结果
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);
}
}
控制台打印信息:
(终止广播后):
(修改广播后):
(1)无序广播:发送方发出后,几乎同时到达多个广播接收者处,某个接收者不能接收到广播后进行一番处理后传给下一个接收者,并且无法终止广播继续传播;
Context.sendBroadcast(intent);
(2)有序广播:广播接收者需要提前设置优先级,优先级高的先接收到广播,优先级数值为-1000~1000,在AndroidManifest.xml的设置;比如存在3个广播接收者A、B、C,优先级A>B>C,因此A最先收到广播,当A收到广播后,可以向广播中添加一些数据给下一个接收者(intent.putExtra()),或者终止广播(abortBroadcast());
Context.sendOrderedBroadcast(intent);
一个服务是具有一个较长生命周期且没有用户界面的程序。例如:一个正在从播放列表中播放歌曲的媒体播放器。
(1)使用startService()方法启动Service,调用者与Service之间没有关系,即使调用者退出了,Service仍然运行。Service不会自动销毁,需要外部调用stopService()方法或在Service内部调用stopSelf()方法,此时Service的onDestroy()方法被调用。
(2)使用bindService()方法启动Service,调用者与Service绑定在了一起,调用者一旦销毁,Service也就终止了,调用者需要解绑时可调用unBindService()方法。Service被解绑或调用者销毁时,Service经历onUnbind() > onDestroy()的过程。
– 应用程序能够将它们的数据保存到文件、SQLite数据库中,甚至是任何有效的设备中。当需要将当前应用数据与其它应用共享时,ContentProvider类实现了一组标准方法,从而能够让其它的应用保存或读取此ContentProvider处理的各种数据类型。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。