Activity

2018-09-08  本文已影响0人  刘nene

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");}


7.Activity的启动过程?

上一篇下一篇

猜你喜欢

热点阅读