Activity-的-36-大难点,你会几个?「建议收藏」
Posted Java德克士
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activity-的-36-大难点,你会几个?「建议收藏」相关的知识,希望对你有一定的参考价值。
前言
- 学
android
有一段时间了,一直都只顾着学新的东西,最近发现很多平常用的少的东西竟让都忘了,趁着这两天,打算把有关Activity
的内容以问题的形式梳理出来,也供大家查缺补漏。
本文中,我将一改往日写博客的习惯,全文用 XMind 将所有知识点以思维导图的形式呈现,欢迎大家食用~~
文章目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OaIsxnq4-1623500717051)(//upload-images.jianshu.io/upload_images/16244318-c05596651a346d9e.png?imageMogr2/auto-orient/strip|imageView2/2/w/1172/format/webp)]
方便大家学习,我在 GitHub 上建立个 仓库
-
仓库内容与博客同步更新。由于我在
稀土掘金
简书
CSDN
博客园
等站点,都有新内容发布。所以大家可以直接关注该仓库,以免错过精彩内容!
神图
- 在开始之前,先让我们看看
Android
的activity
到底都有哪些东西? - 借一张网上很火的图带你了解
Activity
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aPP965cQ-1623500717054)(//upload-images.jianshu.io/upload_images/16244318-c38025440f80bd45.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)]
一、 生命周期
- 我们生命周期先看看具体有哪些方法回调,在逐一攻破:
1.1 Dialog 弹出时
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rjZGsAaA-1623500717056)(//upload-images.jianshu.io/upload_images/16244318-f0db324232e2e892.png?imageMogr2/auto-orient/strip|imageView2/2/w/658/format/webp)]
- 如果是单纯是创建的
dialog
,Activity
并不会执行生命周期的方法 - 但是如果是跳转到一个不是全屏的
Activity
的话, 当然就是按照正常的生命周期来执行了 - 即
onPasue()
->onPause()
( 不会执行原Activity
的onStop()
, 否则上个页面就不显示了 )
1.2 横竖屏切换时
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0n23ZRUx-1623500717058)(//upload-images.jianshu.io/upload_images/16244318-617ed81279008470.png?imageMogr2/auto-orient/strip|imageView2/2/w/1145/format/webp)]
-
不设置
Activity
的android:configChanges
时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次 -
设置
Activity
的android:configChanges="orientation"
时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次 -
设置
Activity
的android:configChanges="orientation|keyboardHidden"
时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged
方法 -
注意:还有一点,非常重要,一个
Android
的变更细节!当API >12
时,需要加入screenSize
属性,否则屏幕切换时即使你设置了orientation
系统也会重建Activity
!
1.3 不同场景下 Activity 生命周期的变化过程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IQBLzYYE-1623500717060)(//upload-images.jianshu.io/upload_images/16244318-81211be143279d1c.png?imageMogr2/auto-orient/strip|imageView2/2/w/738/format/webp)]
- 启动
Activity
:onCreate()
—>onStart()
—>onResume()
,Activity
进入运行状态。 - 锁屏时会执行
onPause()
和onStop()
, 而开屏时则应该执行onStart()
onResume()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qrYrI5h9-1623500717062)(//upload-images.jianshu.io/upload_images/16244318-13e69d3b360f61dd.png?imageMogr2/auto-orient/strip|imageView2/2/w/820/format/webp)]
Activity
退居后台: 当前Activity
转到新的Activity
界面或按Home
键回到主屏:onPause()
—>onStop()
,进入停滞状态。Activity
返回前台:onRestart()
—>onStart()
—>onResume()
,再次回到运行状态。Activity
退居后台: 且系统内存不足, 系统会杀死这个后台状态的Activity
,若再次回到这个Activity
,则会走onCreate()
-->onStart()
—>onResume()
1.4 将一个 Activity 设置成窗口的样式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jdjdq6Og-1623500717063)(//upload-images.jianshu.io/upload_images/16244318-dab1c065ff797e2d.png?imageMogr2/auto-orient/strip|imageView2/2/w/688/format/webp)]
只需要给我们的 Activity
配置如下属性即可。
android:theme="@android:style/Theme.Dialog"
1.5 退出已调用多个 Activity 的 Application
- 通常情况用户退出一个
Activity
只需按返回键,我们写代码想退出activity
直接调用finish()
方法就行。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MfvTfvKw-1623500717064)(//upload-images.jianshu.io/upload_images/16244318-76880290ac2eceb7.png?imageMogr2/auto-orient/strip|imageView2/2/w/1113/format/webp)]
- 发送特定广播:
- 在需要结束应用时, 发送一个特定的广播,每个
Activity
收到广播后,关闭 即可。 - 给某个
activity
注册接受接受广播的意图registerReceiver(receiver, filter)
- 如果过接受到的是 关闭
activity
的广播activity finish()
掉
- 递归退出
- 就调用
finish()
方法 把当前的Activity
退出 - 在打开新的
Activity
时使用startActivityForResult
, 然后自己加标志, 在onActivityResult
中处理, 递归关闭。
- 其实
- 也可以通过
intent
的flag
来实现intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
激活一个新的activity
。 - 此时如果该任务栈中已经有该
Activity
, 那么系统会把这个Activity
上面的所有Activity
干掉。 - 其实相当于给
Activity
配置的启动模式为singleTask
。
- 记录打开的
Activity
- 每打开一个
Activity
, 就记录下来。 - 在需要退出时 , 关闭每一个
Activity
1.6 锁定屏与解锁屏幕,Activity 如何执行生命周期
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TCwYuNjg-1623500717065)(//upload-images.jianshu.io/upload_images/16244318-cf84e36e8300ce00?imageMogr2/auto-orient/strip|imageView2/2/w/767/format/webp)]
- 锁屏时会执行
onPause()
和onStop()
, 而开屏时则应该执行onStart()
onResume()
1.7 修改 Activity 进入和退出动画
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2OK1CWfC-1623500717066)(//upload-images.jianshu.io/upload_images/16244318-ddce04028a9d2f7a.png?imageMogr2/auto-orient/strip|imageView2/2/w/1072/format/webp)]
- 可以通过两种方式 , 一是通过定义
Activity
的主题 ,二是通过覆写Activity
的overridePendingTransition
方法。 - 通过设置主题样式在
styles.xml
中编辑代码 , 添加themes.xml
文件:在AndroidManifest.xml
中给指定的Activity
指定theme
。 - 覆写
overridePendingTransition
方法:overridePendingTransition(R.anim.fade, R.anim.hold)
;
1.8 Activity 的四种状态
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yXBc8nop-1623500717067)(//upload-images.jianshu.io/upload_images/16244318-2c137889038ab97d.png?imageMogr2/auto-orient/strip|imageView2/2/w/864/format/webp)]
runnig
:用户可以点击,activity
处于栈顶状态。paused
:activity
失去焦点的时候,被一个非全屏的activity
占据或者被一个透明的activity
覆盖,这个状态的activity
并没有销毁,它所有的状态信息和成员变量仍然存在,只是不能够被点击。(内存紧张的情况,这个activity
有可能被回收)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bYJ9ojLP-1623500717068)(//upload-images.jianshu.io/upload_images/16244318-23816af0b1eca4ac.png?imageMogr2/auto-orient/strip|imageView2/2/w/525/format/webp)]
stopped
:这个activity
被另外一个activity
完全覆盖,但是这个activity
的所有状态信息和成员变量仍然存在(除了内存紧张)killed
:这个activity
已经被销毁,其所有的状态信息和成员变量已经不存在了。
1.9 如何处理异常退出
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-exwctSsq-1623500717068)(//upload-images.jianshu.io/upload_images/16244318-754e8e8718f544de.png?imageMogr2/auto-orient/strip|imageView2/2/w/1096/format/webp)]
Activity
异常退出的时候 -->onPause()
-->onSaveInstanceState()
-->onStop()
-->onDestory()
- 需要注意的是
onSaveInstanceState()
方法与onPause
并没有严格的先后关系,有可能在onPause
之前,也有可能在其后面调用,但会在onStop()
方法之前调用 - 异常退出后又重新启动该
Activity
-->onCreate()
-->onStart()
-->onRestoreInstanceState()
-->onResume()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JTr5vjiP-1623500717069)(//upload-images.jianshu.io/upload_images/16244318-553e7989067464ef?imageMogr2/auto-orient/strip|imageView2/2/w/714/format/webp)]
- 搞懂这个生命周期的执行后就可以回答了,首先要知道面试官的意思:是要重新启动并恢复这个
Activity
还是说直接退出整个app
- 如果要恢复则要在
onSaveInstanceState()
中进行保存数据并在onRestoreInstanceState()
中进行恢复 - 如果是要退出
app
的话就要捕获全局的异常信息,并退出app
- 当然个人建议是使用
UncaughtExceotionHandler
来捕获全局异常进行退出app
的操作,这样会减少之前崩溃所造成的后遗症!
1.10 什么是 onNewIntent
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-22ttCt8j-1623500717070)(//upload-images.jianshu.io/upload_images/16244318-f51c740191f71db3.png?imageMogr2/auto-orient/strip|imageView2/2/w/909/format/webp)]
-
如果
IntentActivity
处于任务栈的顶端,也就是说之前打开过的Activity
,现在处于onPause
、onStop
状态的话,其他应用再发送Intent
的话 -
执行顺序为:
onNewIntent
,onRestart
,onStart
,onResume
。
二、 启动模式
2.1 启动模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6TOHqEey-1623500717071)(//upload-images.jianshu.io/upload_images/16244318-841c3ac72d203f22.png?imageMogr2/auto-orient/strip|imageView2/2/w/412/format/webp)]
Activity
一共有四种launchMode
:standard
、singleTop
、singleTask
、singleInstance
。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tiTXONYj-1623500717072)(//upload-images.jianshu.io/upload_images/16244318-e03245faf705a25b.png?imageMogr2/auto-orient/strip|imageView2/2/w/865/format/webp)]
Standard
模式(默认模式)
-
说明: 每次启动一个
Activity
都会又一次创建一个新的实例入栈,无论这个实例是否存在。 -
生命周期:每次被创建的实例
Activity
的生命周期符合典型情况,它的onCreate
、onStart
、onResume
都会被调用。 -
举例:此时
Activity
栈中以此有A
、B
、C
三个Activity
,此时C处于栈顶,启动模式为Standard
模式。若在C Activity
中加入点击事件,须要跳转到还有一个同类型的C Activity
。结果是还有一个C Activity
进入栈中,成为栈顶。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-koyibBc9-1623500717073)(//upload-images.jianshu.io/upload_images/16244318-4539fa155b5bbb48.png?imageMogr2/auto-orient/strip|imageView2/2/w/826/format/webp)]
SingleTop
模式(栈顶复用模式)
-
说明:分两种处理情况:须要创建的
Activity
已经处于栈顶时,此时会直接复用栈顶的Activity
。不会再创建新的Activity
;若须要创建的Activity
不处于栈顶,此时会又一次创建一个新的Activity
入栈,同Standard
模式一样。 -
生命周期:若情况一中栈顶的
Activity
被直接复用时,它的onCreate
、onStart
不会被系统调用,由于它并没有发生改变。可是一个新的方法onNewIntent
会被回调(Activity
被正常创建时不会回调此方法)。 -
举例:此时
Activity
栈中以此有A
、B
、C
三个Activity
,此时C
处于栈顶,启动模式为SingleTop
模式。情况一:在C Activity
中加入点击事件,须要跳转到还有一个同类型的C Activity
。结果是直接复用栈顶的C Activity
。情况二:在C Activity
中加入点击事件,须要跳转到还有一个A Activity
。结果是创建一个新的Activity
入栈。成为栈顶。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fSuWEi64-1623500717074)(//upload-images.jianshu.io/upload_images/16244318-f3c8df0a4374bfb9.png?imageMogr2/auto-orient/strip|imageView2/2/w/933/format/webp)]
SingleTask
模式(栈内复用模式)
-
说明:若须要创建的
Activity
已经处于栈中时,此时不会创建新的Activity
,而是将存在栈中的Activity
上面的其他Activity
所有销毁,使它成为栈顶。 -
如果是在别的应用程序中启动它,则会新建一个
task
,并在该task中启动这个Activity
,singleTask
允许别的Activity
与其在一个task
中共存,也就是说,如果我在这个singleTask
的实例中再打开新的Activity
,这个新的Activity
还是会在singleTask
的实例的task
中。 -
生命周期:同
SingleTop
模式中的情况一同样。仅仅会又一次回调Activity
中的onNewIntent
方法 -
举例:此时
Activity
栈中以此有A
、B
、C
三个Activity
。此时C
处于栈顶,启动模式为SingleTask
模式。情况一:在C Activity
中加入点击事件,须要跳转到还有一个同类型的C Activity
。结果是直接用栈顶的C Activity
。情况二:在C Activity
中加入点击事件,须要跳转到还有一个A Activity
。结果是将A Activity
上面的B
、C
所有销毁,使A Activity
成为栈顶。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1YbOL6FZ-1623500717075)(//upload-images.jianshu.io/upload_images/16244318-e15cdb9bac76cf2b.png?imageMogr2/auto-orient/strip|imageView2/2/w/823/format/webp)]
SingleInstance
模式(单实例模式)
-
说明:
SingleInstance
比较特殊,是全局单例模式,是一种加强的SingleTask
模式。它除了具有它所有特性外,还加强了一点:只有一个实例,并且这个实例独立运行在一个task
中,这个task
只有这个实例,不允许有别的Activity
存在。 -
这个经常使用于系统中的应用,比如
Launch
、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。了解就可以。 -
举例:比方
A Activity
是该模式,启动A
后。系统会为它创建一个单独的任务栈,由于栈内复用的特性。兴许的请求均不会创建新的Activity
,除非这个独特的任务栈被系统销毁。
2.2 启动模式的使用方式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QhduJOx5-1623500717075)(//upload-images.jianshu.io/upload_images/16244318-0bf3323f5de217a1.png?imageMogr2/auto-orient/strip|imageView2/2/w/1068/format/webp)]
- 在
Manifest.xml
中指定Activity
启动模式
- 一种静态的指定方法
- 在
Manifest.xml
文件里声明Activity
的同一时候指定它的启动模式 - 这样在代码中跳转时会依照指定的模式来创建
Activity
。
- 启动
Activity
时。在Intent
中指定启动模式去创建Activity
- 一种动态的启动模式
- 在
new
一个Intent
后 - 通过
Intent
的addFlags
方法去动态指定一个启动模式。
- 注意:以上两种方式都能够为
Activity
指定启动模式,可是二者还是有差别的。
-
优先级:动态指定方式即另外一种比第一种优先级要高,若两者同一时候存在,以另外一种方式为准。
-
限定范围:第一种方式无法为
Activity
直接指定FLAG_ACTIVITY_CLEAR_TOP
标识,另外一种方式无法为Activity
指定singleInstance
模式。
2.3 启动模式的实际应用场景
这四种模式中的
Standard
模式是最普通的一种,没有什么特别注意。而SingleInstance
模式是整个系统的单例模式,在我们的应用中一般不会应用到。所以,这里就具体解说SingleTop
和SingleTask
模式的运用场景:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EQY5Fnjg-1623500717076)(//upload-images.jianshu.io/upload_images/16244318-8b919570e41e5aa1.png?imageMogr2/auto-orient/strip|imageView2/2/w/1084/format/webp)]
SingleTask
模式的运用场景
- 最常见的应用场景就是保持我们应用开启后仅仅有一个
Activity
的实例。 - 最典型的样例就是应用中展示的主页(
Home
页)。 - 假设用户在主页跳转到其他页面,运行多次操作后想返回到主页,假设不使用
SingleTask
模式,在点击返回的过程中会多次看到主页,这明显就是设计不合理了。
SingleTop
模式的运用场景
- 假设你在当前的
Activity
中又要启动同类型的Activity
- 此时建议将此类型
Activity
的启动模式指定为SingleTop
,能够降低Activity的创建,节省内存!
- 注意:复用
Activity
时的生命周期回调
- 这里还须要考虑一个
Activity
跳转时携带页面參数的问题。 - 由于当一个
Activity
设置了SingleTop
或者SingleTask
模式后,跳转此Activity
出现复用原有Activity
的情况时,此Activity
的onCreate
方法将不会再次运行。onCreate
方法仅仅会在第一次创建Activity
时被运行。 - 而一般
onCreate
方法中会进行该页面的数据初始化、UI
初始化,假设页面的展示数据无关页面跳转传递的參数,则不必操心此问题 - 若页面展示的数据就是通过
getInten()
方法来获取,那么问题就会出现:getInten()
获取的一直都是老数据,根本无法接收跳转时传送的新数据!
- 以下,通过一个样例来具体解释:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pp4qAq49-1623500717077)(//upload-images.jianshu.io/upload_images/16244318-b5cce57cd2ca25f1?imageMogr2/auto-orient/strip|imageView2/2/w/474/format/webp)]
-
以上代码中的
CourseDetailActivity
在配置文件里设置了启动模式是SingleTop
模式,依据上面启动模式的介绍可得知,当CourseDetailActivity
处于栈顶时。 -
再次跳转页面到
CourseDetailActivity
时会直接复用原有的Activity
,并且此页面须要展示的数据是从getIntent()
方法得来,可是initData()
方法不会再次被调用,此时页面就无法显示新的数据。 -
当然这样的情况系统早就为我们想过了,这时我们须要另外一个回调
onNewIntent(Intent intent)
方法。此方法会传入最新的intent
,这样我们就能够解决上述问题。这里建议的方法是又一次去setIntent
。然后又一次去初始化数据和UI
。代码例如以下所看到的:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hzWAioFI-1623500717078)(//upload-images.jianshu.io/upload_images/16244318-e7e7a33d1eea39d2?imageMogr2/auto-orient/strip|imageView2/2/w/377/format/webp)]
- 这样,在一个页面中能够反复跳转并显示不同的内容。
2.4 快速启动一个 Activity
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KiJrJDpw-1623500717079)(//upload-images.jianshu.io/upload_images/16244318-91fee1ebbbf12708.png?imageMogr2/auto-orient/strip|imageView2/2/w/720/format/webp)]
- 这个问题其实也是比较简单的,就是不要在
Activity
的onCreate
方法中执行过多繁重的操作,并且在onPasue
方法中同样不能做过多的耗时操作。
2.5 启动流程
-
注意!这里并不是要回答
Activity
的生命周期!
2.6 Activity 的 Flags
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FNY9DoKR-1623500717080)(//upload-images.jianshu.io/upload_images/16244318-ce89b874f1d9d75b.png?imageMogr2/auto-orient/strip|imageView2/2/w/703/format/webp)]
-
标记位既能够设定Activity的启动模式,如同上面介绍的,在动态指定启动模式,比方
FLAG_ACTIVITY_NEW_TASK
和FLAG_ACTIVITY_SINGLE_TOP
等。它还能够影响Activity
的运行状态 ,比方FLAG_ACTIVITY_CLEAN_TOP
和FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
等。 -
以下介绍几个基本的标记位,切勿死记,理解几个就可以,须要时再查官方文档。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-71njNq91-1623500717081)(//upload-images.jianshu.io/upload_images/16244318-8fe1b260dbb5d10b.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)]
FLAG_ACTIVITY_NEW_TASK
- 作用是为
Activity
指定“SingleTask”
启动模式。跟在AndroidMainfest.xml
指定效果同样
FLAG_ACTIVITY_SINGLE_TOP
- 作用是为
Activity
指定“SingleTop”
启动模式,跟在AndroidMainfest.xml
指定效果同样。
FLAG_ACTIVITY_CLEAN_TOP
- 具有此标记位的
Activity
,启动时会将与该Activity
在同一任务栈的其他Activity
出栈。 - 一般与
SingleTask
启动模式一起出现。 - 它会完毕
SingleTask
的作用。 - 但事实上
SingleTask
启动模式默认具有此标记位的作用
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- 具有此标记位的
Activity
不会出如今历史Activity
的列表中 - 使用场景:当某些情况下我们不希望用户通过历史列表回到
Activity
时,此标记位便体现了它的效果。 - 它等同于在
xml
中指定Activity
的属性.
2.7 onNewInstent()方法什么时候执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kJ8oHFdJ-1623500717082)(//upload-images.jianshu.io/upload_images/16244318-068d32bedb78ea60.png?imageMogr2/auto-orient/strip|imageView2/2/w/800/format/webp)]
这个是启动模式中的了,当此 Activity
的实例已经存在,并且此时的启动模式为 SingleTask
和 SingleInstance
,另外当这个实例位于栈顶且启动模式为 SingleTop
时也会触发 onNewInstent()
。
三、 数据
3.1 Activity 间通过 Intent 传递数据大小限制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sr2IEqBH-1623500717082)(//upload-images.jianshu.io/upload_images/16244318-6d7805be70b4da03.png?imageMogr2/auto-orient/strip|imageView2/2/w/814/format/webp)]
Intent
在传递数据时是有大小限制的,这里官方并未详细说明,不过通过实验的方法可以测出数据应该被限制在1MB
之内(1024KB
)- 我们采用传递
Bitmap
的方法,发现当图片大小超过1024
(准确地说是1020
左右)的时候,程序就会出现闪退、停止运行等异常(不同的手机反应不同) - 因此可以判断
Intent
的传输容量在1MB
之内。
3.2 内存不足时系统会杀掉后台的Activity,若需要进行一些临时状态的保存,在哪个方法进行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EvyoWuZs-1623500717083)(//upload-images.jianshu.io/upload_images/16244318-b78e45c0980be0da.png?imageMogr2/auto-orient/strip|imageView2/2/w/1020/format/webp)]
-
Activity
的onSaveInstanceState()
和onRestoreInstanceState()
并不是生命周期方法,它们不同于onCreate()
、onPause()
等生命周期方法,它们并不一定会被触发。 -
onSaveInstanceState()
方法,当应用遇到意外情况(如:内存不足、用户直接按Home
键)由系统销毁一个Activity
,onSaveInstanceState()
会被调用。 -
但是当用户主动去销毁一个
Activity
时,例如在应用中按返回键,onSaveInstanceState()
就不会被调用。 -
除非该
activity
不是被用户主动销毁的,通常onSaveInstanceState()
只适合用于保存一些临时性的状态,而onPause()
适合用于数据的持久化保存。
3.3 onSaveInstanceState() 被执行的场景
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NDzEAkN1-1623500717084)(//upload-images.jianshu.io/upload_images/16244318-6f962e729b71b5a0.png?imageMogr2/auto-orient/strip|imageView2/2/w/1020/format/webp)]
- 系统不知道你按下
HOME
后要运行多少其他的程序,自然也不知道activity A
是否会被销毁 - 因此系统都会调用
onSaveInstanceState()
,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则:
- 当用户按下
HOME
键时 - 长按
HOME
键,选择运行其他的程序时 - 锁屏时
- 从
activity A
中启动一个新的activity
时 - 屏幕方向切换时
3.4 两个 Activity 之间跳转时必然会执行的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b5f1x56Y-1623500717085)(//upload-images.jianshu.io/upload_images/16244318-96a0b92386b73a1b.png?imageMogr2/auto-orient/strip|imageView2/2/w/1117/format/webp)]
一般情况下比如说有两个 activity
, 分别叫 A
, B
,当在 A
里面激活 B
组件的时候, A
会调用 onPause()
方法,然后 B
调用 onCreate()
, onStart()
, onResume()
。
这个时候 B
覆盖了窗体, A
会调用 onStop()
方法. 如果 B
是个透明的,或者 是对话框的样式, 就不会调用 A
的 onStop()
方法。
3.5 用 Intent 去启动一个Activity 之外的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sLlkB1Ay-1623500717086)(//upload-images.jianshu.io/upload_images/16244318-6fc880c70e2b7778.png?imageMogr2/auto-orient/strip|imageView2/2/w/1104/format/webp)]
- 使用
adb shell am
命令
am
启动一个activity
adb shell am start com.example.fuchenxuan/.MainActivity
am
发送一个广播,使用action
adb shell am broadcast -a magcomm.action.TOUCH_LETTER
3.6 scheme 跳转协议
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6KUNKfxf-1623500717087)(//upload-images.jianshu.io/upload_images/16244318-4ab1ec70a07a5b78.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)]
3.6.1 定义
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KxR0sl35-1623500717088)(//upload-images.jianshu.io/upload_images/16244318-fbea9887f80f9cac.png?imageMogr2/auto-orient/strip|imageView2/2/w/566/format/webp)]
-
服务器可以定制化跳转
app
页面 -
app
可以通过Scheme
跳转到另一个app
页面 -
可以通过
h5
页面跳转app
原生页面
3.6.2 协议格式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Q27Oq0m-1623500717088)(//upload-images.jianshu.io/upload_images/16244318-fd4995e6f7f65774?imageMogr2/auto-orient/strip|imageView2/2/w/615/format/webp)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AHQzHwwF-1623500717089)(//upload-images.jianshu.io/upload_images/16244318-acfc6362e674b4df.png?imageMogr2/auto-orient/strip|imageView2/2/w/439/format/webp)]
-
qh
代表Scheme
协议名称 -
test
代表Scheme
作用的地址域 -
8080
代表改路径的端口号 -
/goods
代表的是指定页面(路径) -
goodsId
和name
代表传递的两个参数
3.6.3 Scheme使用
- 定义一个
Scheme
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ERPvqLFp-1623500717090)(//upload-images.jianshu.io/upload_images/16244318-0289d6379a6e909d?imageMogr2/auto-orient/strip|imageView2/2/w/790/format/webp)]
- 获取
Scheme
跳转的参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B2CLQaKE-1623500717092)(//upload-images.jianshu.io/upload_images/16244318-d03a25dd8b6f74d9?imageMogr2/auto-orient/strip|imageView2/2/w/685/format/webp)]
- 调用方式
- 原生调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mOJJ7CUq-1623500717093)(//upload-images.jianshu.io/upload_images/16244318-c9a51b8445cf955d?imageMogr2/auto-orient/strip|imageView2/2/w/949/format/webp)]
- html调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0P0kZP3m-1623500717094)(//upload-images.jianshu.io/upload_images/16244318-062fc36ad3aa1d37?imageMogr2/auto-orient/strip|imageView2/2/w/582/format/webp)]
- 判断某个Scheme是否有效
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oHvPs6ew-1623500717095)(//upload-images.jianshu.io/upload_images/16244318-369d3fd25ef8c04b?imageMogr2/auto-orient/strip|imageView2/2/w/976/format/webp)]
- 关于scheme跳转协议,可以查看下面的博客,站在巨人的肩膀上,才能看得更远
Android产品研发(十一)–>应用内跳转Scheme协议
四、 Context
4.1 Context , Activity , Appliction 的区别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yfp6uJ1G-1623500717095)(//upload-images.jianshu.io/upload_images/16244318-554c90e9457d8578.png?imageMogr2/auto-orient/strip|imageView2/2/w/1139/format/webp)]
- 相同:
Activity
和Application
都是Context
的子类。 Context
从字面上理解就是上下文的意思, 在实际应用中它也确实是起到了管理 上下文环境中各个参数和变量的总用, 方便我们可以简单的访问到各种资源。- 不同:维护的生命周期不同。
Context
维护的是当前的Activity
的生命周期,Application
维护的是整个项目的生命周期。 - 使用
context
的时候, 小心内存泄露, 防止内存泄露
4.2 Context 是什么
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uz6tx8zZ-1623500717096)(//upload-images.jianshu.io/upload_images/16244318-4c5dcfbcde8e55d7.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)]
-
它描述的是一个应用程序环境的信息,即上下文。
-
该类是一个抽象(
abstract class
)类,Android
提供了该抽象类的具体实 现类(ContextIml
)。 -
通过它我们可以获取应用程序的资源和类, 也包括一些应用级别操作, 例如:启动一个
Activity
,发送广播,接受Intent
,信息,等。
4.2.1 附加一张 Context 继承关系图
[图片上传失败…(image-de33df-1572405738902)]
4.3 获取当前屏幕 Activity 的对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yuCsi3ts-1623500717097)(//upload-images.jianshu.io/upload_images/16244318-ff776455eddac223.png?imageMogr2/auto-orient/strip|imageView2/2/w/808/format/webp)]
- 使用 ActivityLifecycleCallbacks
Android 如何获取当前Activity实例对象?
4.4 Activity 的管理机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TivBNpUi-1623500717098)(//upload-images.jianshu.io/upload_images/16244318-afc5af8dc81a3ad4.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)]
-
面试官问这个问题,想看看大家对Activity了解是否深入:
- 什么是 ActivityRecord
- 什么是 TaskRecord
- 什么是 ActivityManagerService
4.5 什么是 Activity
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sC44AnP3-1623500717099)(//upload-images.jianshu.io/upload_images/16244318-05404f0108412d60.png?imageMogr2/auto-orient/strip|imageView2/2/w/782/format/webp)]
- 四大组件之一,通常一个用户交互界面对应一个
activity
。 activity
是Context
的子类,同时实现了window.callback
和keyevent.callback
,可以处理与窗体用户交互的事件。- 开发中常用的有
FragmentActivity
、ListActivity
、TabActivity
(Android 4.0
被Fragment
取代)
五、 进程
5.1 Android 进程优先级
- 前台 / 可见 / 服务 / 后台 / 空
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-atfOZJs3-1623500717100)(//upload-images.jianshu.io/upload_images/16244318-44a431f48ffa68e6.png?imageMogr2/auto-orient/strip|imageView2/2/w/499/format/webp)]
5.1.1 前台进程:Foreground process
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hi6HQIfe-1623500717101)(//upload-images.jianshu.io/upload_images/16244318-0c0d22d6909a8b86.png?imageMogr2/auto-orient/strip|imageView2/2/w/657/format/webp)]
- 用户正在交互的
Activity
(onResume()
) - 当某个
Service
绑定正在交互的Activity
- 被主动调用为前台
Service
(startForeground()
) - 组件正在执行生命周期的回调(
onCreate()
、onStart()
、onDestory()
) BroadcastReceiver
正在执行onReceive()
5.1.2 可见进程:Visible process
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KnZxaJ2u-1623500717102)(//upload-images.jianshu.io/upload_images/16244318-26a46163d7ba7686.png?imageMogr2/auto-orient/strip|imageView2/2/w/538/format/webp)]
- 我们的
Activity
处在onPause()
(没有进入onStop()
) - 绑定到前台
Activity
的Service
5.1.3 服务进程:Service process
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iAq3h4p8-1623500717103)(//upload-images.jianshu.io/upload_images/16244318-a555f4d3ea82e820.png?imageMogr2/auto-orient/strip|imageView2/2/w/395/format/webp)]
- 简单的
startService()
启动。
5.1.4 后台进程:Background process
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OdWWYyFn-1623500717104)(//upload-images.jianshu.io/upload_images/16244318-c0889192411af3f5.png?imageMogr2/auto-orient/strip|imageView2/2/w/595/format/webp)]
- 对用户没有直接影响的进程 —
Activity
处于onStop()
的时候。 android:process=":xxx"
5.1.5 空进程:Empty process
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jkbt51pd-1623500717105)(//upload-images.jianshu.io/upload_images/16244318-a35bbb6e95ea6ee1.png?imageMogr2/auto-orient/strip|imageView2/2/w/833/format/webp)]
- 不含有任何的活动的组件。(
Android
设计的,处于缓存的目的,为了第二次启动更快,采取的一个权衡)
5.2 可见进程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hANjU0l2-1623500717105)(//upload-images.jianshu.io/upload_images/16244318-6b4107d41048b48a?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)]
可见进程指部分程序界面能够被用户看见,却不在前台与用户交互的进程。例如,我们在一个界面上弹出一个对话框(该对话框是一个新的
Activity
),那么在对话框后面的原界面是可见的,但是并没有与用户进行交互,那么原界面就是可见进程。
- 一个进程满足下面任何一个条件都被认为是可视的:
- 寄宿着一个不是前台的活动,但是它对用户仍可见(它的
onPause()
方法已经被调用)。举例来说,这可能发生在,如果一个前台活动在一个对话框(其他进程的)运行之后仍然是可视的,比如输入法的弹出时。 - 寄宿着一个服务,该服务绑定到一个可视的活动。
- 一个可视进程被认为是及其重要的且不会被杀死,除非为了保持前台进程运行。
5.3 服务进程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qWhJ2tKB-1623500717106)(//upload-images.jianshu.io/upload_images/16244318-246de29b025b51c1.png?imageMogr2/auto-orient/strip|imageView2/2/w/675/format/webp)]
-
服务进程是通过
startService()
方法启动的进程,但不属于前台进程和可见进程。例如,在后台播放音乐或者在后台下载就是服务进程。 -
系统保持它们运行,除非没有足够内存来保证所有的前台进程和可视进程。
5.4 后台进程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OBLb5UFF-1623500717107)(//upload-images.jianshu.io/upload_images/16244318-bc203fcf95f9c010.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)]
- 后台进程是一个保持着一个当前对用户不可视的活动(已经调用
Activity
对象的onStop()
方法)(如果还有除了UI
线程外其他线程在运行话,不受影响)。
例如我正在使用
Home
键让
- 这些进程没有直接影响用户体验,并且可以在任何时候被杀以收回内存用于一个前台、可视、服务进程。
- 一般地有很多后台进程运行着,因此它们保持在一个
LRU
(least recently used
,即最近最少使用,如果您学过操作系统的话会觉得它很熟悉,跟内存的页面置换算法LRU
一样)列表以确保最近使用最多的活动的进程最后被杀。
5.5 空进程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XXyQ1Xpp-1623500717108)(//upload-images.jianshu.io/upload_images/16244318-1b4d5e8c0a54c2fc.png?imageMogr2/auto-orient/strip|imageView2/2/w/978/format/webp)]
-
空进程是一个没有保持活跃的应用程序组件的进程,不包含任何活跃组件。
-
保持这个进程可用的唯一原因是作为一个
cache
以提高下次启动组件的速度。系统进程杀死这些进程,以在进程cache
和潜在的内核cache
之间平衡整个系统资源。 -
android
进程的回收顺序从先到后分别是:空进程,后台进程,服务进程,可见进程,前台进程。
5.6 什么是 ANR,如何避免
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wDGHl1OC-1623500717108)(//upload-images.jianshu.io/upload_images/16244318-84e738fa20fc4ccf.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)]
5.6.1 什么是ANR
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NtBuiEPV-1623500717109)(//upload-images.jianshu.io/upload_images/16244318-e56bcf09dc177d76.png?imageMogr2/auto-orient/strip|imageView2/2/w/1007/format/webp)]
ANR
,全称为Application Not Responding
。- 在
Android
中,如果你的应用程序有一段时间没有响应,系统会向用户显示一个对话框,这个对话框称作应用程序无响应对话框。
5.6.2 用户行为
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MeAQGfiK-1623500717110)(//upload-images.jianshu.io/upload_images/16244318-1af18f0aca868992.png?imageMogr2/auto-orient/strip|imageView2/2/w/667/format/webp)]
- 用户可以选择让程序继续运行,也可以让程序停止运行。
- 他们在使用你的应用程序时,并不希望每次都要处理这个对话框。
- 因此,在程序里对响应性能的设计很重要,这样,系统不会显示
ANR
给用户。
5.6.3 Android不同组件ANR超时时间不同
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h4Riipdo-1623500717111)(//upload-images.jianshu.io/upload_images/16244318-c0ab19879be511e3.png?imageMogr2/auto-orient/strip|imageView2/2/w/647/format/webp)]
- 不同的组件发生
ANR
的时间不一样,主线程(Activity
、Service
)是5
秒,BroadCastReceiver
是10
秒。
5.6.4 解决方案
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CqmlHBLM-1623500717112)(//upload-images.jianshu.io/upload_images/16244318-b69ae51831d2bef5.png?imageMogr2/auto-orient/strip|imageView2/2/w/877/format/webp)]
- 将所有耗时操作,比如访问网络,
Socket
通信,查询大量SQL
语句,复杂逻辑计算等都放在子线程中去,然后通过handler.sendMessage
、runonUITread
、AsyncTask
等方式更新UI
,以确保用户界面操作的流畅度。 - 如果耗时操作需要让用户等待,那么可以在界面上显示进度条。
5.7 android的任务栈 Task
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gU7SOqEn-1623500717112)(//upload-images.jianshu.io/upload_images/16244318-37d53e1e3b799b73.png?imageMogr2/auto-orient/strip|imageView2/2/w/1067/format/webp)]
- 一个
Task
包含的就是activity
集合,android
系统可以通过任务栈有序的管理activity
- 一个app当中可能不止一个任务栈,在某些情况下,一个
activity
也可以独享一个任务栈(singleInstance
模式启动的activity
)
总结
- 本文基本涵盖了
Android Activity
的所有知识点。对于App
启动、AMS
希望大家能根据文中链接或者Google
搜索的形式继续展开学习。 重点
:关于Android
的四大组件,到现在为止我才总结完 Activity ,马上我将继续针对,Service
,BroadcastRecevier
等,以及事件分发、滑动冲突、新能优化等重要模块,进行全面总结,欢迎大家关注 _yuanhao 的 简书 ,方便及时接收更新
码字不易,你的点赞是我总结的最大动力!
-
由于我在「稀土掘金」「简书」「
CSDN
」「博客园」等站点,都有新内容发布。所以大家可以直接关注我的GitHub
仓库,以免错过精彩内容! -
一万多字长文,加上精美思维导图,记得点赞哦,
作者:_yuanhao
最后说一下我的学习路线
其实很简单就下面这张图,含概了Android所有需要学的知识点,一共8大板块:
- 架构师筑基必备技能
- Android框架体系架构(高级UI+FrameWork源码)
- 360°Androidapp全方位性能调优
- 设计思想解读开源框架
- NDK模块开发
- 移动架构师专题项目实战环节
- 移动架构师不可不学习微信小程序
- 混合开发的flutter
Android学习的资料
我呢,把上面八大板块的分支都系统的做了一份学习系统的资料和视频,大概就下面这些,我就不全部写出来了,不然太长了影响大家的阅读。需要的小伙伴可以私信我【进阶】我免费分享给大家,或者直接点击下面链接领取,谢谢大家这么久以来的支持。
如果你有其他需要的话,也可以在GitHub上查看,下面的资料也会陆续上传到Github
330页PDF Android学习核心笔记(内含上面8大板块)
Android学习的系统对应视频
总结
我希望通过我自己的学习方法来帮助大家去提升技术:
-
1、多看书、看源码和做项目,平时多种总结
-
2、不能停留在一些基本api的使用上,应该往更深层次的方向去研究,比如activity、view的内部运行机制,比如Android内存优化,比如aidl,比如JNI等,并不仅仅停留在会用,而要通过阅读源码,理解其实现原理
-
3、同时对架构是有一定要求的,架构是抽象的,但是设计模式是具体的,所以一定要加强下设计模式的学习
-
4、android的方向也很多,高级UI,移动架构师,数据结构与算法和音视频FFMpeg解码,如果你对其中一项比较感兴趣,就大胆的进阶吧!
F Android学习核心笔记(内含上面8大板块)**
[外链图片转存中…(img-O1uRAjYl-1623500717114)]
Android学习的系统对应视频
[外链图片转存中…(img-xKMUyTTG-1623500717115)]
总结
我希望通过我自己的学习方法来帮助大家去提升技术:
-
1、多看书、看源码和做项目,平时多种总结
-
2、不能停留在一些基本api的使用上,应该往更深层次的方向去研究,比如activity、view的内部运行机制,比如Android内存优化,比如aidl,比如JNI等,并不仅仅停留在会用,而要通过阅读源码,理解其实现原理
-
3、同时对架构是有一定要求的,架构是抽象的,但是设计模式是具体的,所以一定要加强下设计模式的学习
-
4、android的方向也很多,高级UI,移动架构师,数据结构与算法和音视频FFMpeg解码,如果你对其中一项比较感兴趣,就大胆的进阶吧!
希望大家多多点赞,转发,评论加关注,你们的支持就是我继续下去的动力!加油!
以上是关于Activity-的-36-大难点,你会几个?「建议收藏」的主要内容,如果未能解决你的问题,请参考以下文章