Android
有一段时间了,一直都只顾着学新的东西,最近发现很多平常用的少的东西竟让都忘了,趁着这两天,打算把有关 Activity
的内容以问题的形式梳理出来,也供大家查缺补漏。本文中,我将一改往日写博客的习惯,全文用
XMind
将所有知识点以思维导图的形式呈现,欢迎大家食用~~
仓库内容与博客同步更新。由于我在 稀土掘金
简书
CSDN
博客园
等站点,都有新内容发布。所以大家可以直接关注该仓库,以免错过精彩内容!
仓库地址:
超级干货!精心归纳 Android
、JVM
、算法等,各位帅气的老铁支持一下!给个 Star !
Android
的 activity
到底都有哪些东西?Activity
dialog
,Activity
并不会执行生命周期的方法Activity
的话, 当然就是按照正常的生命周期来执行了onPasue()
-> onPause()
( 不会执行原 Activity
的 onStop()
, 否则上个页面就不显示了 )不设置 Activity
的 android:configChanges
时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
设置 Activity
的 android:configChanges="orientation"
时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
设置 Activity
的 android:configChanges="orientation|keyboardHidden"
时,切屏不会重新调用各个生命周期,只会执行 onConfigurationChanged
方法
注意:还有一点,非常重要,一个 Android
的变更细节!当 API >12
时,需要加入 screenSize
属性,否则屏幕切换时即使你设置了 orientation
系统也会重建 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()
只需要给我们的 Activity
配置如下属性即可。
android:theme="@android:style/Theme.Dialog"
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
onPause()
和 onStop()
, 而开屏时则应该执行 onStart()
onResume()
Activity
的主题 ,二是通过覆写 Activity
的 overridePendingTransition
方法。styles.xml
中编辑代码 , 添加 themes.xml
文件:在 AndroidManifest.xml
中给指定的 Activity
指定 theme
。overridePendingTransition
方法:overridePendingTransition(R.anim.fade, R.anim.hold)
;runnig
:用户可以点击,activity
处于栈顶状态。paused
:activity
失去焦点的时候,被一个非全屏的 activity
占据或者被一个透明的 activity
覆盖,这个状态的 activity
并没有销毁,它所有的状态信息和成员变量仍然存在,只是不能够被点击。(内存紧张的情况,这个 activity
有可能被回收)stopped
:这个 activity
被另外一个 activity
完全覆盖,但是这个 activity
的所有状态信息和成员变量仍然存在(除了内存紧张)killed
:这个 activity
已经被销毁,其所有的状态信息和成员变量已经不存在了。Activity
异常退出的时候 --> onPause()
--> onSaveInstanceState()
--> onStop()
--> onDestory()
onSaveInstanceState()
方法与 onPause
并没有严格的先后关系,有可能在 onPause
之前,也有可能在其后面调用,但会在 onStop()
方法之前调用Activity
--> onCreate()
--> onStart()
--> onRestoreInstanceState()
--> onResume()
Activity
还是说直接退出整个 app
onSaveInstanceState()
中进行保存数据并在 onRestoreInstanceState()
中进行恢复app
的话就要捕获全局的异常信息,并退出 app
UncaughtExceotionHandler
来捕获全局异常进行退出 app
的操作,这样会减少之前崩溃所造成的后遗症!如果 IntentActivity
处于任务栈的顶端,也就是说之前打开过的 Activity
,现在处于 onPause
、 onStop
状态的话,其他应用再发送 Intent
的话
执行顺序为:onNewIntent
,onRestart
,onStart
,onResume
。
Activity
一共有四种 launchMode
:standard
、singleTop
、singleTask
、singleInstance
。Standard
模式(默认模式)说明: 每次启动一个 Activity
都会又一次创建一个新的实例入栈,无论这个实例是否存在。
生命周期:每次被创建的实例 Activity
的生命周期符合典型情况,它的 onCreate
、onStart
、onResume
都会被调用。
举例:此时 Activity
栈中以此有 A
、B
、C
三个 Activity
,此时C处于栈顶,启动模式为 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
,除非这个独特的任务栈被系统销毁。
Manifest.xml
中指定 Activity
启动模式Manifest.xml
文件里声明 Activity
的同一时候指定它的启动模式Activity
。Activity
时。在 Intent
中指定启动模式去创建 Activity
new
一个 Intent
后Intent
的 addFlags
方法去动态指定一个启动模式。Activity
指定启动模式,可是二者还是有差别的。优先级:动态指定方式即另外一种比第一种优先级要高,若两者同一时候存在,以另外一种方式为准。
限定范围:第一种方式无法为 Activity
直接指定 FLAG_ACTIVITY_CLEAR_TOP
标识,另外一种方式无法为 Activity
指定 singleInstance
模式。
这四种模式中的
Standard
模式是最普通的一种,没有什么特别注意。而SingleInstance
模式是整个系统的单例模式,在我们的应用中一般不会应用到。所以,这里就具体解说SingleTop
和SingleTask
模式的运用场景:
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()
获取的一直都是老数据,根本无法接收跳转时传送的新数据!以上代码中的 CourseDetailActivity
在配置文件里设置了启动模式是 SingleTop
模式,依据上面启动模式的介绍可得知,当 CourseDetailActivity
处于栈顶时。
再次跳转页面到 CourseDetailActivity
时会直接复用原有的 Activity
,并且此页面须要展示的数据是从 getIntent()
方法得来,可是 initData()
方法不会再次被调用,此时页面就无法显示新的数据。
当然这样的情况系统早就为我们想过了,这时我们须要另外一个回调 onNewIntent(Intent intent)
方法。此方法会传入最新的 intent
,这样我们就能够解决上述问题。这里建议的方法是又一次去 setIntent
。然后又一次去初始化数据和 UI
。代码例如以下所看到的:
Activity
的 onCreate
方法中执行过多繁重的操作,并且在 onPasue
方法中同样不能做过多的耗时操作。注意!这里并不是要回答 Activity
的生命周期!
3 分钟看懂 Activity
启动流程
标记位既能够设定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
的属性.这个是启动模式中的了,当此 Activity
的实例已经存在,并且此时的启动模式为 SingleTask
和 SingleInstance
,另外当这个实例位于栈顶且启动模式为 SingleTop
时也会触发 onNewInstent()
。
Intent
在传递数据时是有大小限制的,这里官方并未详细说明,不过通过实验的方法可以测出数据应该被限制在 1MB
之内( 1024KB
)Bitmap
的方法,发现当图片大小超过 1024
(准确地说是 1020
左右)的时候,程序就会出现闪退、停止运行等异常(不同的手机反应不同)Intent
的传输容量在 1MB
之内。Activity
的 onSaveInstanceState()
和 onRestoreInstanceState()
并不是生命周期方法,它们不同于 onCreate()
、onPause()
等生命周期方法,它们并不一定会被触发。
onSaveInstanceState()
方法,当应用遇到意外情况(如:内存不足、用户直接按 Home
键)由系统销毁一个 Activity
,onSaveInstanceState()
会被调用。
但是当用户主动去销毁一个 Activity
时,例如在应用中按返回键,onSaveInstanceState()
就不会被调用。
除非该 activity
不是被用户主动销毁的,通常 onSaveInstanceState()
只适合用于保存一些临时性的状态,而 onPause()
适合用于数据的持久化保存。
HOME
后要运行多少其他的程序,自然也不知道 activity A
是否会被销毁onSaveInstanceState()
,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则:HOME
键时HOME
键,选择运行其他的程序时activity A
中启动一个新的 activity
时一般情况下比如说有两个 activity
, 分别叫 A
, B
,当在 A
里面激活 B
组件的时候, A
会调用 onPause()
方法,然后 B
调用 onCreate()
, onStart()
, onResume()
。
这个时候 B
覆盖了窗体, A
会调用 onStop()
方法. 如果 B
是个透明的,或者 是对话框的样式, 就不会调用 A
的 onStop()
方法。
adb shell am
命令am
启动一个 activity
adb shell am start com.example.fuchenxuan/.MainActivity
am
发送一个广播,使用 action
adb shell am broadcast -a magcomm.action.TOUCH_LETTER
服务器可以定制化跳转 app
页面
app
可以通过 Scheme
跳转到另一个 app
页面
可以通过 h5
页面跳转 app
原生页面
qh
代表 Scheme
协议名称
test
代表 Scheme
作用的地址域
8080
代表改路径的端口号
/goods
代表的是指定页面(路径)
goodsId
和 name
代表传递的两个参数
Scheme
Scheme
跳转的参数Activity
和 Application
都是 Context
的子类。Context
从字面上理解就是上下文的意思, 在实际应用中它也确实是起到了管理 上下文环境中各个参数和变量的总用, 方便我们可以简单的访问到各种资源。Context
维护的是当前的 Activity
的生命周期, Application
维护的是整个项目的生命周期。context
的时候, 小心内存泄露, 防止内存泄露它描述的是一个应用程序环境的信息,即上下文。
该类是一个抽象( abstract class
)类, Android
提供了该抽象类的具体实 现类( ContextIml
)。
通过它我们可以获取应用程序的资源和类, 也包括一些应用级别操作, 例如:启动一个 Activity
,发送广播,接受 Intent
,信息,等。
使用 ActivityLifecycleCallbacks
Android 如何获取当前Activity实例对象?
Activity的管理机制
面试官问这个问题,想看看大家对Activity了解是否深入:
activity
。activity
是 Context
的子类,同时实现了 window.callback
和 keyevent.callback
,可以处理与窗体用户交互的事件。FragmentActivity
、ListActivity
、TabActivity
( Android 4.0
被 Fragment
取代)Activity
( onResume()
)Service
绑定正在交互的 Activity
Service
( startForeground()
)onCreate()
、onStart()
、onDestory()
)BroadcastReceiver
正在执行 onReceive()
Activity
处在 onPause()
(没有进入 onStop()
)Activity
的 Service
startService()
启动。Activity
处于 onStop()
的时候。android:process=":xxx"
Android
设计的,处于缓存的目的,为了第二次启动更快,采取的一个权衡)可见进程指部分程序界面能够被用户看见,却不在前台与用户交互的进程。例如,我们在一个界面上弹出一个对话框(该对话框是一个新的
Activity
),那么在对话框后面的原界面是可见的,但是并没有与用户进行交互,那么原界面就是可见进程。
onPause()
方法已经被调用)。举例来说,这可能发生在,如果一个前台活动在一个对话框(其他进程的)运行之后仍然是可视的,比如输入法的弹出时。服务进程是通过 startService()
方法启动的进程,但不属于前台进程和可见进程。例如,在后台播放音乐或者在后台下载就是服务进程。
系统保持它们运行,除非没有足够内存来保证所有的前台进程和可视进程。
Activity
对象的 onStop()
方法)(如果还有除了 UI
线程外其他线程在运行话,不受影响)。例如我正在使用
Home
键让
LRU
( least recently used
,即最近最少使用,如果您学过操作系统的话会觉得它很熟悉,跟内存的页面置换算法 LRU
一样)列表以确保最近使用最多的活动的进程最后被杀。空进程是一个没有保持活跃的应用程序组件的进程,不包含任何活跃组件。
保持这个进程可用的唯一原因是作为一个 cache
以提高下次启动组件的速度。系统进程杀死这些进程,以在进程 cache
和潜在的内核 cache
之间平衡整个系统资源。
android
进程的回收顺序从先到后分别是:空进程,后台进程,服务进程,可见进程,前台进程。
ANR
,全称为 Application Not Responding
。Android
中,如果你的应用程序有一段时间没有响应,系统会向用户显示一个对话框,这个对话框称作应用程序无响应对话框。ANR
给用户。ANR
的时间不一样,主线程( Activity
、Service
)是 5
秒,BroadCastReceiver
是 10
秒。Socket
通信,查询大量 SQL
语句,复杂逻辑计算等都放在子线程中去,然后通过 handler.sendMessage
、runonUITread
、AsyncTask
等方式更新 UI
,以确保用户界面操作的流畅度。Task
包含的就是 activity
集合,android
系统可以通过任务栈有序的管理 activity
activity
也可以独享一个任务栈( singleInstance
模式启动的 activity
)Android Activity
的所有知识点。对于 App
启动、AMS
希望大家能根据文中链接或者 Google
搜索的形式继续展开学习。重点
:关于 Android
的四大组件,到现在为止我才总结完 Activity
,马上我将继续针对,Service
,BroadcastRecevier
等,以及事件分发、滑动冲突、新能优化等重要模块,进行全面总结,欢迎大家关注 _yuanhao 的 CSDN ,方便及时接收更新由于我在「稀土掘金」「简书」「CSDN
」「博客园」等站点,都有新内容发布。所以大家可以直接关注我的 GitHub
仓库,以免错过精彩内容!
仓库地址:
超级干货!精心归纳 Android
、JVM
、算法等,各位帅气的老铁支持一下!给个 Star !
一万多字长文,加上精美思维导图,记得点赞哦,欢迎关注 _yuanhao 的 CSDN ,我们下篇文章见!