文章目录
- 1. Activity生命周期 ?
- 2. Activity A 启动另一个Activity B 会调用哪些方法?如果B是透明主题的又或则是个DialogActivity呢 ?
- 3. 说下onSaveInstanceState、onRestoreInstanceState方法的作用 ? 何时会被调用?
- 4. 为什么不直接在onCreate中恢复数据呢?
- 5. 横竖屏切换的Activity生命周期变化?
- 6. 说下 Activity的四种启动模式、应用场景 ?
- 7. 了解哪些Activity常用的标记位Flags?
- 8. 如何启动其他应用的Activity?
- 9. Application的 Context和 Activity的 Context的区别
- 10. getApplication和getApplicationContext的区别
1. Activity生命周期 ?
2. Activity A 启动另一个Activity B 会调用哪些方法?如果B是透明主题的又或则是个DialogActivity呢 ?
- A: onPause()-B: onCreate()-onStart()-onResume()-A: onStop()
- 透明主题或者dialog A不会调用onStop()
3. 说下onSaveInstanceState、onRestoreInstanceState方法的作用 ? 何时会被调用?
当activity变得容易被系统销毁前,会回调 onSaveInstanceState()
方法,除非该 activity 是被用户主动销毁的(比如按下BACK键)。
- 当用户按下HOME键时。
这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,因此系统会调用onSaveInstanceState(),让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则 - 长按HOME键,选择运行其他的程序时。
- 按下电源按键(关闭屏幕显示)时。
- 从 activity A 中启动一个新的 activity 时。
- 屏幕方向切换时,例如从竖屏切换到横屏时。
android 应用框架中定义的几乎所有 UI 控件都恰当的实现了 onSaveInstanceState()
方法,因此当 activity 被摧毁和重建时, 这些 UI 控件会自动保存和恢复状态数据. 比如 EditText 控件会自动保存和恢复输入的数据,而 CheckBox 控件会自动保存和恢复选中状态.开发者只需要为这些控件指定一个唯一的 ID (通过设置 android:id 属性即可), 剩余的事情就可以自动完成了.如果没有为控件指定 ID, 则这个控件就不会进行自动的数据保存和恢复操作。
4. 为什么不直接在onCreate中恢复数据呢?
因为 onSaveInstanceState
不一定会被调用,所以onCreate()
里的Bundle参数可能为空,如果使用onCreate()
来恢复数据,一定要做非空判断。
而onRestoreInstanceState
的Bundle参数一定不会是空值,因为它只有在上次activity被回收了才会调用。
而且onRestoreInstanceState
是在onStart()
之后被调用的。有时候我们需要onCreate()
中做的一些初始化完成之后再恢复数据,用onRestoreInstanceState
会比较方便。
5. 横竖屏切换的Activity生命周期变化?
如果没有android:configChanges="orientation|screenSize"
配置:
- onConfigurationChanged:
- onPause:
- onSaveInstanceState:(和onPause没有时序关系)
- onStop:
- onDestroy:
- onCreate:
- onStart:
- onRestoreInstanceState:
- onResume:
而按HOME键返回桌面,又马上点击应用图标回到原来页面时,activity生命周期如下:
onPause -> onSaveInstanceState -> onStop -> onRestart -> onStart -> onResume
因为activity没有被系统回收,因此onRestoreInstanceState
没有被调用。
6. 说下 Activity的四种启动模式、应用场景 ?
- Standard:标准模式,系统默认模式,新建一个Activity就在栈中新建一个activity实例
- SingleTop:检查该 Activity 的实例是否位于栈顶,位于栈顶时复用,非栈顶时创建新实例。
- 推送通知栏
- 登录页面
- SingleTask:该 Activity 在整个应用中只存在一个实例,启动此 Activity 时会检查虚拟栈中是否存在它的实例,如果存在直接复用,并把当前Activity之上所有实例全部出栈。
- 主页面
- WebView页面
- 扫一扫页面
- 电商中:购物界面,确认订单界面,付款界面
- SingleInstance:具备 singleTask 模式的所有特性。该模式的 Activity 会启动一个新的任务栈来管理 Activity 实例,并且该实例在整个系统中只有一个。无论从那个任务栈中启动该 Activity,都会是该 Activity 所在的任务栈转移到前台,从而使Activity显示。主要作用是为了在不同程序中共享一个 Activity 实例。
- 经常调用的拨打电话
- 系统通讯录
- 地图类APP 等页面
需注意,后三种方式二次进入的话不是重新创建,而是走
onNewIntent()
,详见下表
7. 了解哪些Activity常用的标记位Flags?
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_SINGLE_TOP
- FLAG_ACTIVITY_CLEAR_TOP
- FALG_ACTIVITY_EXCLUDE_FROM_RECENTS
8. 如何启动其他应用的Activity?
1. 通过包名+类名启动
ActivityA
Intent intent = new Intent();
intent.setClassName("com.wislie.charging","com.wislie.charging.TargetActivity");
startActivity(intent);
TargetActivity
<activity android:name=".TargetActivity" android:exported="true" />
android:exported=“true” 表示Activity能否被另外一个Application的组件启动, true允许启动, false不允许
2. 通过action启动
ActivityA
startActivity(new Intent("com.wislie.intent.target"));
一个 Intent 必须有且只能有一个action(没有缺省值),必须和过滤规则中的器重一个action相匹配,且区分大小写
TargetActivity
category可以不设置,默认值为DEFAULT,但是一旦设置的话,不管有几条,每一条都要能匹配上
<activity android:name=".TargetActivity" >
<intent-filter >
<action android:name="com.wislie.intent.target"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
intent-filter中的
category.DEFAULT
不能缺省,必须要有
3. 通过data启动
ActivityA
Uri uri = Uri.parse("app://com.wislie.app");
Intent intent = new Intent();
intent.setData(uri);
startActivity(intent);
data的匹配规则和action类似
TargetActivity
<activity android:name=".TargetActivity">
<intent-filter>
<action android:name="com.wislie.intent.target" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="com.wislie.app"
android:scheme="app" />
</intent-filter>
</activity>
方放2,3是隐式调用,注意action,category,data的匹配规则,三个字段需要同时匹配,多组intent-filter只需要匹配一组就可以
4. 启动有权限的Activity
倘若设置android:exported="true"
, 要启动的Activity就会暴露出来;为了尽量不暴露Activity,可以为Activity添加权限控制
ActivityA
Intent intent = new Intent();
intent.setClassName("com.wislie.charging", "com.wislie.charging.TargetActivity");
startActivity(intent);
<uses-permission android:name="com.wislie.charging.permission.TargetActivity" />
TargetActivity
<permission android:name="com.wislie.charging.permission.TargetActivity" />
<activity
android:name=".TargetActivity"
android:permission="com.wislie.charging.permission.TargetActivity">
<intent-filter>
<action android:name="com.wislie.intent.target" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
注意事项: 在ActivityA启动TargetActivity时, 如果找不到TargetActivity,就会抛异常,因此需要将启动代码放在try-catch中
9. Application的 Context和 Activity的 Context的区别
对Context的理解可以来说:Context提供了一个应用的运行环境,在Context的大环境里,应用才可以访问资源,才能完成和其他组件、服务 的交互,Context定义了一套基本的功能接口,我们可以理解为一套规范,而Activity和Service是实现这套规范的子类,这么说也许并不准 确,因为这套规范实际是被ContextImpl类统一实现的,Activity和Service只是继承并有选择性地重写了某些规范的实现。
通过对比可以清晰地发现,Service和Application的类继承关系比较像,而Activity还多了一层继承 ContextThemeWrapper,这是因为Activity有主题的概念,而Service是没有界面的服务,Application更是一个抽象的东西,它也是通过Activity类呈现的。
只要把握住一点,凡是跟UI相关的,都应该使用 Activity做为Context来处理;其他的一些操作,Service,Activity,Application等实例都可以,当然了,注意 Context引用的持有,防止内存泄漏。
10. getApplication和getApplicationContext的区别
从这种角度来说,对于第三方应用,一个应用只存在一个Application对象,且通过getApplication和getApplicationContext得到的是同一个对象,两者的区别仅仅是返回类型不同。