这种情况是最普通的状况,Activity 的生命周期会按照上图从上到下的方式走。即:onCreate --> onStart --> onResume --> 运行--> 按返回键结束程序--> onPause-->onStop-->onDestory
对于A:onCreate --> onStart --> onResume --> A运行 --> A发出打开B的Intent --> onPause-->B可见-->onStop
此时,会打开B,B同样会经历一个完整的 Activity 生命周期。等B结束,A再度可见的时候,A会经历:onRestart-->onStart-->onResume
注意:B 这个 Activity 是在 A 的 onPause 执行后才变成可见状态的,所以为了不影响B的显示,最好不要在 onPause 里执行一些耗时操作,可以考虑将这些操作放到 onStop 里,这时 B 已经可见了。
资源相关的系统配置发生改变,举个例子。当前 Activity 处于竖屏状态的时候突然转成横屏,系统配置发生了改变,Activity 就会销毁并且重建,其 onPause, onStop, onDestory 均会被调用。因为实在异常情况下终止的,所以系统会调用 onSaveInstanceState 来保存当前 Activity 状态。这个方法是在 onStop 之前,与 onPause 没有固定的时序关系。当Activity重建的时候系统会把 onSaveInstanceState 所保存的 Bundle 作为对象传递给 onRestoreInstanceState 和 onCreate 方法。
Activity 优先级
前台 Activity ——正在和用户交互的 Activity,优先级最高
可见但非前台 Activity——Activity 中弹出的对话框导致 Activity 可见但无法交互
后台 Activity ——已经被暂停的 Activity,优先级最低
系统内存不足是,会按照以上顺序杀死 Activity,并通过 onSaveInstanceState 和 onRestoreInstanceState 这两个方法来存储和恢复数据。
onSaveInstanceState 在 onStop 之前调用,但不一定在 onPause 之前或者之后。onRestoreInstanceState 在 onStart 之后调用
需要注意的是,onSaveInstanceState 方法只会在 Activity 被异常终止,在 Activity 即将被销毁且有机会重新显示的情况下才会调用
可以总结有下面几种情况
1、当用户按下 HOME 键时。
这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
2、长按 HOME 键,选择运行其他的程序时。
3、按下电源按键(关闭屏幕显示)时。
4、从activity A中启动一个新的 activity 时。
5、屏幕方向切换时,例如从竖屏切换到横屏时。(如果不指定 configchange 属性) 在屏幕切换之前,系统会销毁 activity A,在屏幕切换之后系统又会自动地创建 activity A,所以 onSaveInstanceState 一定会被执行
总而言之,onSaveInstanceState 的调用遵循一个重要原则,即当系统 未经你许可 时销毁了你的 activity,则 onSaveInstanceState 会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据
四种启动模式分别是 standard(标准模式)、singleTop(栈顶复用模式)、singleTask(栈内复用模式)、singleInstance(单实例模式 - 加强的 singleTask 模式)
运用场景:常运用于通知栏弹出 Notification,点击 Notification 跳转到指定的Activity,设置 singleTop 模式
运用场景:可用来退出整个应用。主界面 activity 设为 singleTas 模式,要退出应用时转到主 activity,从而将主 activity 之上的 activity 都清除,然后重写主 activity 的 onNewIntent() 方法,在里面加上 finish(),即可退出所有 activity。这种模式还适用于做浏览器、微博之类的应用
运用场景:这种模式常运用于需要与程序分离的界面,如在 SetupWizard(安装向导)中调用紧急呼叫就是适用这种模式
Intent 是抽象的数据结构,包含了一系列描述某个操作的数据,使得程序在运行时可以在程序中不同组件间通信或启动不同的应用程序。
可以通过startActivity(Intent)启动一个 Activity,sendBroadcast(Intent))发送广播发送给感兴趣的 BroadcastReceiver 组件,startService(android.content.Intent))启动 service,bindService() 绑定服务。
Intent Filter 顾名思义就是 Intent 的过滤器,组件通过定义Intent Filter可以决定哪些隐式Intent可以和该组件进行通讯
Intent分为隐式(implicit)Intent和显式(explicit)Intent。
显式Intent通常用于在程序内部组件间通信,已经明确的定义目标组件的信息,所以不需要系统决策哪个目标组件处理 Intent,如下
- Intent intent =new Intent(CRListDemo.this, GoogleMapDemo.class);
- startActivity(intent);
-
其中 CRListDemo 和 GoogleMapDemo 都是用户自定义的组件,隐式 Intent 不指明目标组件的 class,只定义希望的 Action 及 Data 等相关信息,由系统决定使用哪个目标组件。如发送短信
Android 系统通过对 Intent 和目标组件在 AndroidManifest 文件中定义的(也可以在程序中定义Intent Filter)进行匹配决定和哪个目标组件通讯。如果某组件未定义则只能通过显式的Intent进行通信。Intent 的三个属性用于对目标组件选取的决策,分别是Action、Data(Uri 和 Data Type)、Category。匹配规则如下
a. 发送短信
- Uri uri = Uri.parse("smsto:15800000000");
- Intent i=newIntent(Intent.ACTION_SENDTO, uri);
- i.putExtra("sms_body", "The SMS text");
- startActivity(i);
-
b. 打电话
- Uri dial = Uri.parse("tel:15800000000");
- Intent i=newIntent(Intent.ACTION_DIAL, dial);
- startActivity(i);
-
c. 发送邮件
- Uri email = Uri.parse("mailto:abc@126.com;def@126.com");
- Intent i=newIntent(Intent.ACTION_SENDTO, email);
- startActivity(i);
-
d. 拍照
- Intent i =newIntent(MediaStore.ACTION_IMAGE_CAPTURE);
- String folderPath= Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "AndroidDemo" +File.separator;
- String filePath= folderPath + System.currentTimeMillis() + ".jpg";newFile(folderPath).mkdirs();
- File camerFile=newFile(filePath);
- i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(camerFile));
- startActivityForResult(i,1);
-
e. 浏览网页
- Uri web = Uri.parse("http://www.google.com");
- Intent i=newIntent(Intent.ACTION_VIEW, web);
- startActivity(i);
-
f. 查看联系人
- Intent i =newIntent();
- i.setAction(Intent.ACTION_GET_CONTENT);
- i.setType("vnd.android.cursor.item/phone");
- startActivityForResult(i,1);