Android开发经验谈Android技术知识Android开发

Activity 的 36 大难点,你会几个?「建议收藏」

2019-10-30  本文已影响0人  圆号本昊
Android

前言

本文中,我将一改往日写博客的习惯,全文用 XMind 将所有知识点以思维导图的形式呈现,欢迎大家食用~~

文章目录


文章目录

方便大家学习,我在 GitHub 上建立个 仓库


神图


一张图带你了解 Activity

一、 生命周期


[图片上传失败...(image-76615c-1572405738902)]

1.1 Dialog 弹出时

dialog弹出时

1.2 横竖屏切换时

横竖屏切换时

1.3 不同场景下 Activity 生命周期的变化过程

不同场景下Activity生命周期的变化过程 已启动的 Activity 生命周期的变化

1.4 将一个 Activity 设置成窗口的样式

设置 Activity 成窗口样式

只需要给我们的 Activity 配置如下属性即可。
android:theme="@android:style/Theme.Dialog"

1.5 退出已调用多个 Activity 的 Application

退出调用多个 Activity 的 Application
  1. 在需要结束应用时, 发送一个特定的广播,每个 Activity 收到广播后,关闭 即可。
  2. 给某个 activity 注册接受接受广播的意图 registerReceiver(receiver, filter)
  3. 如果过接受到的是 关闭 activity 的广播 activity finish()
  1. 就调用 finish() 方法 把当前的 Activity 退出
  2. 在打开新的 Activity 时使用 startActivityForResult , 然后自己加标志, 在 onActivityResult 中处理, 递归关闭。
  1. 也可以通过 intentflag 来实现 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 激活一个新的 activity
  2. 此时如果该任务栈中已经有该 Activity , 那么系统会把这个 Activity 上面的所有 Activity 干掉。
  3. 其实相当于给 Activity 配置的启动模式为 singleTask
  1. 每打开一个 Activity , 就记录下来。
  2. 在需要退出时 , 关闭每一个 Activity

1.6 锁定屏与解锁屏幕,Activity 如何执行生命周期

锁定屏与解锁屏幕,Activity如何执行生命周期

1.7 修改 Activity 进入和退出动画

修改 Activity 进入和退出动画

1.8 Activity 的四种状态

四种状态 关闭

1.9 如何处理异常退出

如何处理异常退出 异常退出后又重新启动

1.10 什么是 onNewIntent

onNewIntent

二、 启动模式


2.1 启动模式

启动模式 Standard
  1. 说明: 每次启动一个 Activity 都会又一次创建一个新的实例入栈,无论这个实例是否存在。

  2. 生命周期:每次被创建的实例 Activity 的生命周期符合典型情况,它的 onCreateonStartonResume 都会被调用。

  3. 举例:此时 Activity 栈中以此有 ABC 三个 Activity ,此时C处于栈顶,启动模式为 Standard 模式。若在 C Activity 中加入点击事件,须要跳转到还有一个同类型的 C Activity 。结果是还有一个 C Activity 进入栈中,成为栈顶。

SingleTop
  1. 说明:分两种处理情况:须要创建的 Activity 已经处于栈顶时,此时会直接复用栈顶的 Activity 。不会再创建新的 Activity ;若须要创建的 Activity 不处于栈顶,此时会又一次创建一个新的 Activity 入栈,同 Standard 模式一样。

  2. 生命周期:若情况一中栈顶的 Activity 被直接复用时,它的 onCreateonStart 不会被系统调用,由于它并没有发生改变。可是一个新的方法 onNewIntent 会被回调( Activity 被正常创建时不会回调此方法)。

  3. 举例:此时 Activity 栈中以此有 ABC 三个 Activity ,此时 C 处于栈顶,启动模式为 SingleTop 模式。情况一:在 C Activity 中加入点击事件,须要跳转到还有一个同类型的 C Activity 。结果是直接复用栈顶的 C Activity。情况二:在 C Activity 中加入点击事件,须要跳转到还有一个 A Activity。结果是创建一个新的 Activity 入栈。成为栈顶。

SingleTask
  1. 说明:若须要创建的 Activity 已经处于栈中时,此时不会创建新的 Activity ,而是将存在栈中的 Activity 上面的其他 Activity 所有销毁,使它成为栈顶。

  2. 如果是在别的应用程序中启动它,则会新建一个 task ,并在该task中启动这个 ActivitysingleTask 允许别的 Activity 与其在一个 task 中共存,也就是说,如果我在这个 singleTask 的实例中再打开新的 Activity ,这个新的 Activity 还是会在 singleTask 的实例的 task 中。

  3. 生命周期:同 SingleTop 模式中的情况一同样。仅仅会又一次回调 Activity 中的 onNewIntent 方法

  4. 举例:此时 Activity 栈中以此有 ABC 三个 Activity 。此时 C 处于栈顶,启动模式为 SingleTask 模式。情况一:在 C Activity 中加入点击事件,须要跳转到还有一个同类型的 C Activity 。结果是直接用栈顶的 C Activity 。情况二:在 C Activity 中加入点击事件,须要跳转到还有一个 A Activity 。结果是将 A Activity 上面的 BC 所有销毁,使 A Activity 成为栈顶。

ingleInstance
  1. 说明: SingleInstance 比较特殊,是全局单例模式,是一种加强的 SingleTask 模式。它除了具有它所有特性外,还加强了一点:只有一个实例,并且这个实例独立运行在一个 task 中,这个 task 只有这个实例,不允许有别的 Activity 存在。

  2. 这个经常使用于系统中的应用,比如 Launch 、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。了解就可以。

  3. 举例:比方 A Activity 是该模式,启动 A 后。系统会为它创建一个单独的任务栈,由于栈内复用的特性。兴许的请求均不会创建新的 Activity ,除非这个独特的任务栈被系统销毁。

2.2 启动模式的使用方式

启动模式的使用方式
  1. 一种静态的指定方法
  2. Manifest.xml 文件里声明 Activity 的同一时候指定它的启动模式
  3. 这样在代码中跳转时会依照指定的模式来创建 Activity
  1. 一种动态的启动模式
  2. new 一个 Intent
  3. 通过 IntentaddFlags 方法去动态指定一个启动模式。
  1. 优先级:动态指定方式即另外一种比第一种优先级要高,若两者同一时候存在,以另外一种方式为准。

  2. 限定范围:第一种方式无法为 Activity 直接指定 FLAG_ACTIVITY_CLEAR_TOP 标识,另外一种方式无法为 Activity 指定 singleInstance 模式。

2.3 启动模式的实际应用场景

这四种模式中的 Standard 模式是最普通的一种,没有什么特别注意。而 SingleInstance 模式是整个系统的单例模式,在我们的应用中一般不会应用到。所以,这里就具体解说 SingleTopSingleTask 模式的运用场景:

启动模式的实际应用场景
  1. 最常见的应用场景就是保持我们应用开启后仅仅有一个 Activity 的实例。
  2. 最典型的样例就是应用中展示的主页( Home 页)。
  3. 假设用户在主页跳转到其他页面,运行多次操作后想返回到主页,假设不使用 SingleTask 模式,在点击返回的过程中会多次看到主页,这明显就是设计不合理了。
  1. 假设你在当前的 Activity 中又要启动同类型的 Activity
  2. 此时建议将此类型 Activity 的启动模式指定为 SingleTop ,能够降低Activity的创建,节省内存!
  1. 这里还须要考虑一个 Activity 跳转时携带页面參数的问题。
  2. 由于当一个 Activity 设置了 SingleTop 或者 SingleTask 模式后,跳转此 Activity 出现复用原有 Activity 的情况时,此 ActivityonCreate 方法将不会再次运行。onCreate 方法仅仅会在第一次创建 Activity 时被运行。
  3. 而一般 onCreate 方法中会进行该页面的数据初始化、UI 初始化,假设页面的展示数据无关页面跳转传递的參数,则不必操心此问题
  4. 若页面展示的数据就是通过 getInten() 方法来获取,那么问题就会出现:getInten() 获取的一直都是老数据,根本无法接收跳转时传送的新数据!
图片描述 图片描述

2.4 快速启动一个 Activity

快速启动一个 Activity

2.5 启动流程

2.6 Activity 的 Flags

Activity 的 Flags 几个基本的标记位
  1. 作用是为 Activity 指定 “SingleTask” 启动模式。跟在 AndroidMainfest.xml 指定效果同样
  1. 作用是为 Activity 指定 “SingleTop” 启动模式,跟在 AndroidMainfest.xml 指定效果同样。
  1. 具有此标记位的 Activity ,启动时会将与该 Activity 在同一任务栈的其他 Activity 出栈。
  2. 一般与 SingleTask 启动模式一起出现。
  3. 它会完毕 SingleTask 的作用。
  4. 但事实上 SingleTask 启动模式默认具有此标记位的作用
  1. 具有此标记位的 Activity 不会出如今历史 Activity 的列表中
  2. 使用场景:当某些情况下我们不希望用户通过历史列表回到 Activity 时,此标记位便体现了它的效果。
  3. 它等同于在 xml 中指定 Activity 的属性.

2.7 onNewInstent()方法什么时候执行

onNewInstent()方法什么时候执行

这个是启动模式中的了,当此 Activity 的实例已经存在,并且此时的启动模式为 SingleTaskSingleInstance ,另外当这个实例位于栈顶且启动模式为 SingleTop 时也会触发 onNewInstent()

三、 数据


3.1 Activity 间通过 Intent 传递数据大小限制

Activity 间通过 Intent 传递数据大小限制

3.2 内存不足时系统会杀掉后台的Activity,若需要进行一些临时状态的保存,在哪个方法进行

onSaveInstanceState()

3.3 onSaveInstanceState() 被执行的场景

onSaveInstanceState() 被执行的场景
  1. 当用户按下 HOME 键时
  2. 长按 HOME 键,选择运行其他的程序时
  3. 锁屏时
  4. activity A 中启动一个新的 activity
  5. 屏幕方向切换时

3.4 两个 Activity 之间跳转时必然会执行的方法

两个 Activity 之间跳转时必然会执行的方法

一般情况下比如说有两个 activity , 分别叫 A , B ,当在 A 里面激活 B 组件的时候, A 会调用 onPause() 方法,然后 B 调用 onCreate() , onStart() , onResume()

这个时候 B 覆盖了窗体, A 会调用 onStop() 方法. 如果 B 是个透明的,或者 是对话框的样式, 就不会调用 AonStop() 方法。

3.5 用 Intent 去启动一个Activity 之外的方法

用 Intent 去启动一个Activity 之外的方法
  1. am 启动一个 activity
  2. adb shell am start com.example.fuchenxuan/.MainActivity
  3. am 发送一个广播,使用 action
  4. adb shell am broadcast -a magcomm.action.TOUCH_LETTER

3.6 scheme 跳转协议

scheme跳转协议

3.6.1 定义

定义

3.6.2 协议格式:

协议格式 协议格式

3.6.3 Scheme使用

image image
  1. 原生调用
image
  1. html调用
image
  1. 判断某个Scheme是否有效
image

四、 Context


4.1 Context , Activity , Appliction 的区别

Context, Activity, Appliction 的区别

4.2 Context 是什么

Context 是什么

4.2.1 附加一张 Context 继承关系图

[图片上传失败...(image-de33df-1572405738902)]

4.3 获取当前屏幕 Activity 的对象

获取当前屏幕Activity的对象

4.4 Activity 的管理机制

Activity的管理机制
  1. 什么是 ActivityRecord
  2. 什么是 TaskRecord
  3. 什么是 ActivityManagerService

4.5 什么是 Activity

什么是 Activity

五、 进程


5.1 Android 进程优先级

前台 / 可见 / 服务 / 后台 / 空

5.1.1 前台进程:Foreground process

前台进程:Foreground process

5.1.2 可见进程:Visible process

可见进程:Visible process

5.1.3 服务进程:Service process

服务进程

5.1.4 后台进程:Background process

后台进程:Background process

5.1.5 空进程:Empty process

空进程:Empty process

5.2 可见进程

可见进程

可见进程指部分程序界面能够被用户看见,却不在前台与用户交互的进程。例如,我们在一个界面上弹出一个对话框(该对话框是一个新的 Activity ),那么在对话框后面的原界面是可见的,但是并没有与用户进行交互,那么原界面就是可见进程。

  1. 寄宿着一个不是前台的活动,但是它对用户仍可见(它的 onPause() 方法已经被调用)。举例来说,这可能发生在,如果一个前台活动在一个对话框(其他进程的)运行之后仍然是可视的,比如输入法的弹出时。
  2. 寄宿着一个服务,该服务绑定到一个可视的活动。

5.3 服务进程

服务进程

5.4 后台进程

后台进程

例如我正在使用 qq 和别人聊天,这个时候 qq 是前台进程,但是当我点击 Home 键让 qq 界面消失的时候,这个时候它就转换成了后台进程。

5.5 空进程

空进程

5.6 什么是 ANR,如何避免

什么是 ANR,如何避免

5.6.1 什么是ANR

什么是ANR

5.6.2 用户行为

用户行为

5.6.3 Android不同组件ANR超时时间不同

Android不同组件ANR超时时间不同

5.6.4 解决方案

解决方案
  1. 将所有耗时操作,比如访问网络,Socket 通信,查询大量 SQL 语句,复杂逻辑计算等都放在子线程中去,然后通过 handler.sendMessagerunonUITreadAsyncTask 等方式更新 UI ,以确保用户界面操作的流畅度。
  2. 如果耗时操作需要让用户等待,那么可以在界面上显示进度条。

5.7 android的任务栈 Task

android的任务栈 Task

总结


  1. 本文基本涵盖了 Android Activity 的所有知识点。对于 App 启动、AMS 希望大家能根据文中链接或者 Google 搜索的形式继续展开学习。
  2. 重点:关于 Android 的四大组件,到现在为止我才总结完 Activity ,马上我将继续针对,ServiceBroadcastRecevier 等,以及事件分发、滑动冲突、新能优化等重要模块,进行全面总结,欢迎大家关注 _yuanhao 的 简书 ,方便及时接收更新

码字不易,你的点赞是我总结的最大动力!


Android
上一篇下一篇

猜你喜欢

热点阅读