作者:_yuanhao
链接:
https://www.jianshu.com/p/86c0a4afd28e前言
- 学
有一段时间了,一直都只顾着学新的东西,最近发现很多平常用的少的东西竟让都忘了,趁着这两天,打算把有关Android
的内容以问题的形式梳理出来,也供大家查缺补漏。Activity
本文中,我将一改往日写博客的习惯,全文用 XMind 将所有知识点以思维导图的形式呈现,欢迎大家食用~~
文章目录
-
- *
方便大家学习,我在 GitHub 上建立个 仓库
-
- 仓库内容与博客同步更新。由于我在
稀土掘金
简书
CSDN
等站点,都有新内容发布。所以大家可以直接关注该仓库,以免错过精彩内容!博客园
- 仓库地址:
[超级干货!精心归纳 `Android` 、`JVM` 、算法等,各位帅气的老铁支持一下!给个 Star !](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FFishInWater-1999%2Fandroid_interviews)
神图
-
- 在开始之前,先让我们看看
的Android
到底都有哪些东西?activity
- 借一张网上很火的图带你了解
Activity
一、 生命周期
-
- 先贴一张闻名遐迩的图
- 我们生命周期先看看具体有哪些方法回调,在逐一攻破:
1.1 Dialog 弹出时
- 如果是单纯是创建的
,dialog
并不会执行生命周期的方法Activity
- 但是如果是跳转到一个不是全屏的
的话, 当然就是按照正常的生命周期来执行了Activity
- 即
->onPasue()
( 不会执行原onPause()
Activity
, 否则上个页面就不显示了 )onStop()
1.2 横竖屏切换时
- 不设置
Activity
时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次android:configChanges
- 设置
Activity
时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次android:configChanges="orientation"
-
Activity
时,切屏不会重新调用各个生命周期,只会执行android:configChanges="orientation|keyboardHidden"
方法onConfigurationChanged
- 注意:还有一点,非常重要,一个
的变更细节!当Android
时,需要加入API >12
属性,否则屏幕切换时即使你设置了screenSize
系统也会重建orientation
!Activity
- 横竖屏切换生命周期的执行
1.3 不同场景下 Activity 生命周期的变化过程
- 启动
:Activity
--->onCreate()
onStart()
onResume()
进入运行状态。Activity
- 锁屏时会执行
和onPause()
, 而开屏时则应该执行onStop()
onStart()
onResume()
-
退居后台: 当前Activity
转到新的Activity
界面或按Activity
键回到主屏:Home
onPause()
,进入停滞状态。onStop()
-
返回前台:Activity
onRestart()
onStart()
,再次回到运行状态。onResume()
-
退居后台: 且系统内存不足, 系统会杀死这个后台状态的Activity
,若再次回到这个Activity
,则会走Activity
-->onCreate()
onStart()
onResume()
1.4 将一个 Activity 设置成窗口的样式
只需要给我们的
Activity
配置如下属性即可。
android:theme="@android:style/Theme.Dialog"
1.5 退出已调用多个 Activity 的 Application
- 通常情况用户退出一个
只需按返回键,我们写代码想退出Activity
直接调用activity
方法就行。finish()
- 发送特定广播:
- 在需要结束应用时, 发送一个特定的广播,每个
收到广播后,关闭 即可。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 如何执行生命周期
-
onPause()
onStop()
onStart()
onResume()
1.7 修改 Activity 进入和退出动画
- 可以通过两种方式 , 一是通过定义
的主题 ,二是通过覆写Activity
Activity
方法。overridePendingTransition
- 通过设置主题样式在
中编辑代码 , 添加styles.xml
文件:在themes.xml
中给指定的AndroidManifest.xml
指定Activity
theme
- 覆写
方法:overridePendingTransition
;overridePendingTransition(R.anim.fade, R.anim.hold)
1.8 Activity 的四种状态
-
:用户可以点击,runnig
处于栈顶状态。activity
-
paused
失去焦点的时候,被一个非全屏的activity
占据或者被一个透明的activity
覆盖,这个状态的activity
并没有销毁,它所有的状态信息和成员变量仍然存在,只是不能够被点击。(内存紧张的情况,这个activity
有可能被回收)activity
-
:这个stopped
被另外一个activity
完全覆盖,但是这个activity
的所有状态信息和成员变量仍然存在(除了内存紧张)activity
-
killed
已经被销毁,其所有的状态信息和成员变量已经不存在了。activity
1.9 如何处理异常退出
-
异常退出的时候 -->Activity
onPause()
onSaveInstanceState()
onStop()
onDestory()
- 需要注意的是
方法与onSaveInstanceState()
并没有严格的先后关系,有可能在onPause
之前,也有可能在其后面调用,但会在onPause
方法之前调用onStop()
- 异常退出后又重新启动该
Activity
onCreate()
onStart()
onRestoreInstanceState()
onResume()
- 搞懂这个生命周期的执行后就可以回答了,首先要知道面试官的意思:是要重新启动并恢复这个
还是说直接退出整个Activity
app
- 如果要恢复则要在
中进行保存数据并在onSaveInstanceState()
中进行恢复onRestoreInstanceState()
- 如果是要退出
的话就要捕获全局的异常信息,并退出app
app
- 当然个人建议是使用
来捕获全局异常进行退出UncaughtExceotionHandler
的操作,这样会减少之前崩溃所造成的后遗症!app
1.10 什么是 onNewIntent
- 如果
处于任务栈的顶端,也就是说之前打开过的IntentActivity
,现在处于Activity
、onPause
状态的话,其他应用再发送onStop
的话Intent
- 执行顺序为:
onNewIntent
onRestart
onStart
onResume
二、 启动模式
2.1 启动模式
-
一共有四种Activity
launchMode
standard
singleTop
singleTask
singleInstance
-
模式(默认模式)Standard
- 说明: 每次启动一个
都会又一次创建一个新的实例入栈,无论这个实例是否存在。Activity
- 生命周期:每次被创建的实例
的生命周期符合典型情况,它的Activity
onCreate
onStart
都会被调用。onResume
- 举例:此时
栈中以此有Activity
A
B
三个C
,此时C处于栈顶,启动模式为Activity
模式。若在Standard
中加入点击事件,须要跳转到还有一个同类型的C Activity
。结果是还有一个C Activity
进入栈中,成为栈顶。C Activity
-
模式(栈顶复用模式)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
-
模式(栈内复用模式)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
-
模式(单实例模式)SingleInstance
- 说明:
比较特殊,是全局单例模式,是一种加强的SingleInstance
模式。它除了具有它所有特性外,还加强了一点:只有一个实例,并且这个实例独立运行在一个SingleTask
中,这个task
只有这个实例,不允许有别的task
存在。Activity
- 这个经常使用于系统中的应用,比如
、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。了解就可以。Launch
- 举例:比方
是该模式,启动A Activity
后。系统会为它创建一个单独的任务栈,由于栈内复用的特性。兴许的请求均不会创建新的A
,除非这个独特的任务栈被系统销毁。Activity
2.2 启动模式的使用方式
- 在
中指定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
-
模式的运用场景SingleTask
- 最常见的应用场景就是保持我们应用开启后仅仅有一个
的实例。Activity
- 最典型的样例就是应用中展示的主页(
页)。Home
- 假设用户在主页跳转到其他页面,运行多次操作后想返回到主页,假设不使用
模式,在点击返回的过程中会多次看到主页,这明显就是设计不合理了。SingleTask
-
SingleTop
- 假设你在当前的
中又要启动同类型的Activity
Activity
- 此时建议将此类型
的启动模式指定为Activity
,能够降低Activity的创建,节省内存!SingleTop
- 注意:复用
时的生命周期回调Activity
- 这里还须要考虑一个
跳转时携带页面參数的问题。Activity
- 由于当一个
设置了Activity
或者SingleTop
模式后,跳转此SingleTask
出现复用原有Activity
的情况时,此Activity
Activity
方法将不会再次运行。onCreate
方法仅仅会在第一次创建onCreate
时被运行。Activity
- 而一般
方法中会进行该页面的数据初始化、onCreate
初始化,假设页面的展示数据无关页面跳转传递的參数,则不必操心此问题UI
- 若页面展示的数据就是通过
方法来获取,那么问题就会出现:getInten()
获取的一直都是老数据,根本无法接收跳转时传送的新数据!getInten()
- 以下,通过一个样例来具体解释:
- 以上代码中的
在配置文件里设置了启动模式是CourseDetailActivity
模式,依据上面启动模式的介绍可得知,当SingleTop
处于栈顶时。CourseDetailActivity
- 再次跳转页面到
时会直接复用原有的CourseDetailActivity
,并且此页面须要展示的数据是从Activity
方法得来,可是getIntent()
方法不会再次被调用,此时页面就无法显示新的数据。initData()
- 当然这样的情况系统早就为我们想过了,这时我们须要另外一个回调
方法。此方法会传入最新的onNewIntent(Intent intent)
,这样我们就能够解决上述问题。这里建议的方法是又一次去intent
。然后又一次去初始化数据和setIntent
。代码例如以下所看到的:UI
- 这样,在一个页面中能够反复跳转并显示不同的内容。
2.4 快速启动一个 Activity
- 这个问题其实也是比较简单的,就是不要在
Activity
方法中执行过多繁重的操作,并且在onCreate
方法中同样不能做过多的耗时操作。onPasue
2.5 启动流程
- 注意!这里并不是要回答
的生命周期!Activity
- 3 分钟看懂
启动流程Activity
2.6 Activity 的 Flags
- 标记位既能够设定Activity的启动模式,如同上面介绍的,在动态指定启动模式,比方
FLAG_ACTIVITY_NEW_TASK
等。它还能够影响FLAG_ACTIVITY_SINGLE_TOP
的运行状态 ,比方Activity
FLAG_ACTIVITY_CLEAN_TOP
等。FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- 以下介绍几个基本的标记位,切勿死记,理解几个就可以,须要时再查官方文档。
-
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()方法什么时候执行
这个是启动模式中的了,当此
Activity
的实例已经存在,并且此时的启动模式为
SingleTask
SingleInstance
,另外当这个实例位于栈顶且启动模式为
SingleTop
时也会触发
onNewInstent()
三、 数据
3.1 Activity 间通过 Intent 传递数据大小限制
-
在传递数据时是有大小限制的,这里官方并未详细说明,不过通过实验的方法可以测出数据应该被限制在Intent
之内(1MB
)1024KB
- 我们采用传递
的方法,发现当图片大小超过Bitmap
(准确地说是1024
左右)的时候,程序就会出现闪退、停止运行等异常(不同的手机反应不同)1020
- 因此可以判断
的传输容量在Intent
之内。1MB
3.2 内存不足时系统会杀掉后台的Activity,若需要进行一些临时状态的保存,在哪个方法进行
-
Activity
onSaveInstanceState()
并不是生命周期方法,它们不同于onRestoreInstanceState()
onCreate()
等生命周期方法,它们并不一定会被触发。onPause()
-
方法,当应用遇到意外情况(如:内存不足、用户直接按onSaveInstanceState()
键)由系统销毁一个Home
Activity
会被调用。onSaveInstanceState()
- 但是当用户主动去销毁一个
时,例如在应用中按返回键,Activity
就不会被调用。onSaveInstanceState()
- 除非该
不是被用户主动销毁的,通常activity
只适合用于保存一些临时性的状态,而onSaveInstanceState()
适合用于数据的持久化保存。onPause()
3.3 onSaveInstanceState() 被执行的场景
- 系统不知道你按下
后要运行多少其他的程序,自然也不知道HOME
是否会被销毁activity A
- 因此系统都会调用
,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则:onSaveInstanceState()
- 当用户按下
键时HOME
- 长按
键,选择运行其他的程序时HOME
- 锁屏时
- 从
中启动一个新的activity A
时activity
- 屏幕方向切换时
3.4 两个 Activity 之间跳转时必然会执行的方法
一般情况下比如说有两个
activity
, 分别叫
A
,
B
,当在
A
里面激活
B
组件的时候,
A
会调用
onPause()
方法,然后
B
调用
onCreate()
onStart()
onResume()
这个时候
B
覆盖了窗体,
A
onStop()
方法. 如果
B
是个透明的,或者 是对话框的样式, 就不会调用
A
onStop()
3.5 用 Intent 去启动一个Activity 之外的方法
- 使用
命令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 跳转协议
3.6.1 定义
- 服务器可以定制化跳转
页面app
-
可以通过app
跳转到另一个Scheme
app
-
页面跳转h5
原生页面app
3.6.2 协议格式:
-
代表qh
协议名称Scheme
-
test
作用的地址域Scheme
-
代表改路径的端口号8080
-
代表的是指定页面(路径)/goods
-
goodsId
代表传递的两个参数name
3.6.3 Scheme使用
- 定义一个
Scheme
- 获取
跳转的参数Scheme
- 调用方式
- 原生调用
- html调用
- 判断某个Scheme是否有效
- 关于scheme跳转协议,可以查看下面的博客,站在巨人的肩膀上,才能看得更远
[Android产品研发(十一)-->应用内跳转Scheme协议](https://links.jianshu.com/go?to=http%3A%2F%2Fblog.csdn.net%2Fqq_23547831%2Farticle%2Fdetails%2F51685310)
四、 Context
4.1 Context , Activity , Appliction 的区别
- 相同:
Activity
都是Application
的子类。Context
-
从字面上理解就是上下文的意思, 在实际应用中它也确实是起到了管理 上下文环境中各个参数和变量的总用, 方便我们可以简单的访问到各种资源。Context
- 不同:维护的生命周期不同。
维护的是当前的Context
的生命周期,Activity
维护的是整个项目的生命周期。Application
-
的时候, 小心内存泄露, 防止内存泄露context
4.2 Context 是什么
- 它描述的是一个应用程序环境的信息,即上下文。
- 该类是一个抽象(
)类,abstract class
提供了该抽象类的具体实 现类(Android
)。ContextIml
- 通过它我们可以获取应用程序的资源和类, 也包括一些应用级别操作, 例如:启动一个
,发送广播,接受Activity
,信息,等。Intent
4.2.1 附加一张 Context 继承关系图
4.3 获取当前屏幕 Activity 的对象
- 使用 ActivityLifecycleCallbacks
[Android 如何获取当前Activity实例对象?](https://links.jianshu.com/go?to=http%3A%2F%2Fblog.csdn.net%2Fvfush%2Farticle%2Fdetails%2F51483436)
4.4 Activity 的管理机制
- Activity的管理机制
- 面试官问这个问题,想看看大家对Activity了解是否深入:
- 什么是 ActivityRecord
- 什么是 TaskRecord
- 什么是 ActivityManagerService
4.5 什么是 Activity
- 四大组件之一,通常一个用户交互界面对应一个
activity
-
是activity
的子类,同时实现了Context
window.callback
,可以处理与窗体用户交互的事件。keyevent.callback
- 开发中常用的有
FragmentActivity
ListActivity
(TabActivity
被Android 4.0
取代)Fragment
五、 进程
5.1 Android 进程优先级
- 前台 / 可见 / 服务 / 后台 / 空
5.1.1 前台进程:Foreground process
- 用户正在交互的
Activity
onResume()
- 当某个
绑定正在交互的Service
Activity
- 被主动调用为前台
Service
startForeground()
- 组件正在执行生命周期的回调(
onCreate()
onStart()
onDestory()
-
正在执行BroadcastReceiver
onReceive()
5.1.2 可见进程:Visible process
- 我们的
处在Activity
(没有进入onPause()
onStop()
- 绑定到前台
Activity
Service
5.1.3 服务进程:Service process
- 简单的
启动。startService()
5.1.4 后台进程:Background process
- 对用户没有直接影响的进程 ---
处于Activity
的时候。onStop()
-
android:process=":xxx"
5.1.5 空进程:Empty process
- 不含有任何的活动的组件。(
设计的,处于缓存的目的,为了第二次启动更快,采取的一个权衡)Android
5.2 可见进程
可见进程指部分程序界面能够被用户看见,却不在前台与用户交互的进程。例如,我们在一个界面上弹出一个对话框(该对话框是一个新的 Activity
),那么在对话框后面的原界面是可见的,但是并没有与用户进行交互,那么原界面就是可见进程。
- 一个进程满足下面任何一个条件都被认为是可视的:
- 寄宿着一个不是前台的活动,但是它对用户仍可见(它的
方法已经被调用)。举例来说,这可能发生在,如果一个前台活动在一个对话框(其他进程的)运行之后仍然是可视的,比如输入法的弹出时。onPause()
- 寄宿着一个服务,该服务绑定到一个可视的活动。
- 一个可视进程被认为是及其重要的且不会被杀死,除非为了保持前台进程运行。
5.3 服务进程
- 服务进程是通过
方法启动的进程,但不属于前台进程和可见进程。例如,在后台播放音乐或者在后台下载就是服务进程。startService()
- 系统保持它们运行,除非没有足够内存来保证所有的前台进程和可视进程。
5.4 后台进程
- 后台进程是一个保持着一个当前对用户不可视的活动(已经调用
对象的Activity
方法)(如果还有除了onStop()
线程外其他线程在运行话,不受影响)。UI
例如我正在使用和别人聊天,这个时候
是前台进程,但是当我点击
键让
Home
界面消失的时候,这个时候它就转换成了后台进程。
- 这些进程没有直接影响用户体验,并且可以在任何时候被杀以收回内存用于一个前台、可视、服务进程。
- 一般地有很多后台进程运行着,因此它们保持在一个
LRU
,即最近最少使用,如果您学过操作系统的话会觉得它很熟悉,跟内存的页面置换算法least recently used
一样)列表以确保最近使用最多的活动的进程最后被杀。LRU
5.5 空进程
- 空进程是一个没有保持活跃的应用程序组件的进程,不包含任何活跃组件。
- 保持这个进程可用的唯一原因是作为一个
以提高下次启动组件的速度。系统进程杀死这些进程,以在进程cache
和潜在的内核cache
之间平衡整个系统资源。cache
-
进程的回收顺序从先到后分别是:空进程,后台进程,服务进程,可见进程,前台进程。android
5.6 什么是 ANR,如何避免
5.6.1 什么是ANR
-
,全称为ANR
Application Not Responding
-
中,如果你的应用程序有一段时间没有响应,系统会向用户显示一个对话框,这个对话框称作应用程序无响应对话框。Android
5.6.2 用户行为
- 用户可以选择让程序继续运行,也可以让程序停止运行。
- 他们在使用你的应用程序时,并不希望每次都要处理这个对话框。
- 因此,在程序里对响应性能的设计很重要,这样,系统不会显示
给用户。ANR
5.6.3 Android不同组件ANR超时时间不同
- 不同的组件发生
的时间不一样,主线程(ANR
Activity
)是Service
秒,5
BroadCastReceiver
秒。10
5.6.4 解决方案
- 将所有耗时操作,比如访问网络,
通信,查询大量Socket
语句,复杂逻辑计算等都放在子线程中去,然后通过SQL
handler.sendMessage
runonUITread
等方式更新AsyncTask
,以确保用户界面操作的流畅度。UI
- 如果耗时操作需要让用户等待,那么可以在界面上显示进度条。
5.7 android的任务栈 Task
-
包含的就是Task
集合,activity
系统可以通过任务栈有序的管理android
activity
- 一个app当中可能不止一个任务栈,在某些情况下,一个
也可以独享一个任务栈(activity
模式启动的singleInstance
activity
总结
- 本文基本涵盖了
的所有知识点。对于Android Activity
启动、App
希望大家能根据文中链接或者AMS
搜索的形式继续展开学习。Google
-
:关于重点
的四大组件,到现在为止我才总结完 Activity ,马上我将继续针对,Android
Service
等,以及事件分发、滑动冲突、新能优化等重要模块,进行全面总结,欢迎大家关注 _yuanhao 的 简书 ,方便及时接收更新BroadcastRecevier
推荐阅读:
2019年鸿洋大神最新整理一线互联网公司Android中高级面试题总结(附答案解析) 临近毕业,2020春招困惑你的十大问题,你中招了吗? Android社招最全面试题