1.Activity的生命周期
activity生命周期图示这些方法都是两两对应的,onCreate创建与onDestroy销毁;onStart可见与onStop不可见;onResume可编辑(即焦点)与onPause;
onRestart方法调用:在Activity被onStop后,但是没有被onDestroy,在再次启动此Activity时就调用onRestart(而不再调用onCreate)方法;如果被onDestroy了,则是调用onCreate方法。
2.Activity生命周期的切换过程
①启动一个Activity:
onCreate()-->onStart()-->onResume()
②打开一个新Activity:
旧Activity的onPause() -->新Activity的onCreate()-->onStart()-->onResume()-->旧Activity的onStop()
③返回到旧Activity:
新Activity的onPause()-->旧Activity的onRestart()-->onStart()-->onResume()-->新Activity的onStop()-->onDestory();
④Activity1上弹出对话框Activity2:
Activity1的onPause()-->Activity2的onCreate()-->onStart()-->onResume()
⑤两个activity关闭屏幕/按Home键:
Activity2的onPause()-->onStop()-->Activity1的onStop()
⑥点亮屏幕/回到前台:
Activity2的onRestart()-->onStart()-->Activity1的onRestart()-->onStart()-->Activity2的onResume()
⑦关闭对话框Activity2:
Activity2的onPause()-->Activity1的onResume()-->Activity2的onStop()-->onDestroy()
⑧销毁Activity1:
onPause()-->onStop()-->onDestroy()
3.onSaveInstanceState 和 onRestoreInstanceState 区别
Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState() 会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。
系统配置发生改变导致Activity被杀死并重新创建onSaveInstanceState的调用时机
(1)、当用户按下HOME键时。
这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,因此系统会调用onSaveInstanceState(),让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
(2)、长按HOME键,选择运行其他的程序时。
(3)、按下电源按键(关闭屏幕显示)时。
(4)、从activity A中启动一个新的activity时。
(5)、屏幕方向切换时,例如从竖屏切换到横屏时。
onSaveInstanceState-->onPause(不定)-->onStop-->
onDestroy-->onCreate-->onStart-->onRestoreInstanceState-->onResume
(6)、资源内存不足低优先级被杀死
1)前台Activity——正在和用户交互的Activity,优先级最高
2)可见但是非前台Activity——比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户直接交互
3)后台Activity——已经被暂停的Activity,比如执行了onStop,优先级最低
当系统内存不足时,系统就会按照上述优先级去杀死目标Activity所在的进程,并且后续通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据,如果一个进程中没有四大组件在执行,那么这个进程将很快被系统杀死,比较好的方法是将后台工作放入Service中从而保证进程有一定的优先级,这样就不会轻易地被系统杀死。
onRestoreInstanceState()调用时机
onRestoreInstanceState()被调用的前提是,activity A“确实”被系统销毁了,而如果仅仅是停留在有这种可能性的情况下,则该方法不会被调用。
onSaveInstanceState()方法的默认实现
如果我们没有覆写onSaveInstanceState()方法, 此方法的默认实现会自动保存activity中的某些状态数据, 比如activity中各种UI控件的状态.。android应用框架中定义的几乎所有UI控件都恰当的实现了onSaveInstanceState()方法,因此当activity被摧毁和重建时, 这些UI控件会自动保存和恢复状态数据. 比如EditText控件会自动保存和恢复输入的数据,而CheckBox控件会自动保存和恢复选中状态.开发者只需要为这些控件指定一个唯一的ID(通过设置android:id属性即可), 剩余的事情就可以自动完成了.如果没有为控件指定ID, 则这个控件就不会进行自动的数据保存和恢复操作。
由上所述, 如果我们需要覆写onSaveInstanceState()方法, 一般会在第一行代码中调用该方法的默认实现:super.onSaveInstanceState(outState)。
4.如何避免activity重建
可在AndroidManifest.xml中对应的Activity中设置android:configChanges="orientation|keyboardHidden|screenSize"。此时再次旋转屏幕时,该Activity不会被系统杀死和重建,只会调用onConfigurationChanged。因此,当配置程序需要响应配置改变,指定configChanges属性,重写onConfigurationChanged方法即可。
5.Activity的四种启动模式?
a.standard 标准模式
创建 Activity 的新实例并向其传送 Intent
b.singleTop 栈顶复用模式
在栈顶存在的实例中intent,则系统会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建 Activity 的新实例
c.singleTask 栈内复用模式
如果该Activity在一个任务栈中存在,都不会重新创建,并回调onNewIntent(intent)方法。如果不存在,系统会先寻找是否存在需要的栈,如果不存在该栈,就创建一个任务栈,并把该Activity放进去
d.singleInstance 单实例模式
该 Activity 始终是其任务唯一仅有的成员;由此 Activity 启动的任何 Activity 均在单独的任务中打开。
任务和返回栈
使用
a.在AndroidManifest.xml中给对应的Activity设定属性android:launchMode="standard|singleInstance|single Task|singleTop"
b.通过标记位设定,方法是intent.addFlags(Intent.xxx)
①FLAG_ACTIVITY_SINGLE_TOP:对应singleTop启动模式。
②FLAG_ACTIVITY_NEW_TASK :对应singleTask模式。
来控制Acivity任务栈。
任务栈是一种后进先出的结构。位于栈顶的Activity处于焦点状态,当按下back按钮的时候,栈内的Activity会一个一个的出栈,并且调用其onDestory()方法。如果栈内没有Activity,那么系统就会回收这个栈,每个APP默认只有一个栈,以APP的包名来命名
6.如何启动其他应用的Activity?
Android提供了在一个App中启动另一个App中的Activity的能力,这使我们的程序很容易就可以调用其他程序的功能,从而就丰富了我们App的功能。比如在微信中发送一个位置信息,对方可以点击这个位置信息启动腾讯地图并导航。
a.显示
显示调用b.隐式
筛选匹配组件
隐式调用在manifest中注册
manifest注册a.action匹配规则:
要求intent中的action存在且必须和intent-filter中的其中一个action相同。
区分大小写。
b.category匹配规则:
intent中的category可以不存在,这是因为此时系统给该Activity默认加上了< category android:name="android.intent.category.DEAFAULT" />属性值。
除上述情况外,有其他category,则要求intent中的category和intent-filter中的所有category 相同。
c.data匹配规则:
如果intent-filter中有定义data,那么Intent中也必须也要定义date。
data主要由mimeType(媒体类型)和URI组成。在匹配时通过intent.setDataAndType(Uri data, String type)方法对date进行设置。
要求和action相似:如果没有指定URI,默认值为content和file; 有多组data规则时,匹配其中一组即可。
隐式启动判断
a.PackageManager
Intent intent =newIntent();
intent.setAction(Intent.ACTION_BATTERY_LOW);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
intent.setDataAndType(Uri.EMPTY,"video/mpeg");
PackageManager packageManager = getPackageManager();
List infoList = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
Log.i(TAG, infoList.size() +"");
if(infoList.size() !=0) { startActivity(intent);}
else{ Log.e(TAG,"没有匹配到Activity");}
b.ComponentName
Intent intent =newIntent();
intent.setAction(Intent.ACTION_BATTERY_LOW);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
intent.setDataAndType(Uri.EMPTY,"video/mpeg");
ComponentName name = intent.resolveActivity(getPackageManager());
if(name !=null){ startActivity(intent);}else{ Log.e(TAG,"没有匹配到Activity");}
网友评论