安卓Activity生命周期详解(androidactivity生命周期)
大家好,今天本篇文章就来给大家分享安卓Activity生命周期详解,以及androidactivity生命周期对应的知识和见解,内容偏长哪个,大家要耐心看完哦,希望对各位有所帮助,不要忘了收藏本站喔。
1Activity的生命周期及常见回调顺序
关于Activity的生命周期相信不少人都觉得自己很了解了,毕竟大多数入门的时候都会首先学这个,但事实真的是这样吗?当初我也是这样想,直到在面试的时候栽了跟头~ 在哪跌倒就在哪爬起来,本文带你全面的了解一下Activity的生命周期,面试再问到也不怕啦
首先按照官方生命周期流程图逐个解释生命周期回调
当Activity首次创建的时候触发,这是生命周期的第一个方法,我们需要重写这个回调,并在调用setContentView()去加载界面布局资源,以及实例化一些变量。该方法有一个参数savedInstanceState,该参数包含Activity先前保存状态的Bundle对象。如果Activity是由于异常情况(切换横竖屏,内存不足等)被杀掉的,则Bundle对象的值不为null,否则Bundle的值为null。所以如果想要在onCreate()中做恢复工作需要对Bundle判断是否为空。不过建议在onRestoreInstanceState()方法中做恢复工作,因为该方法一旦被调用则Bundle不会为空。
表示Activity正在重新启动。一般情况下,当当前Activity从不可见重新变为可见状态时,onRestart就会被调用。这种情形一般是用户行为导致的,比如用户按Home键切换到桌面或打开了另一个新的Activity,接着用户又回到了这个Actvity。
表示Activity正在被启动,即将开始,这时Activity已经出现了,但是还没有出现在前台,无法与用户交互。这个时候可以理解为Activity已经显示出来,但是我们还看不到。
相信很多人会有疑问,什么叫Activity已经显示出来了,但是看不到???因为我们能看到的都是View或者和View有关联的东西,而Activity确实是没有什么直观的东西让我们看到的。所以这里说的看不到其实是看不到View,因为此时View还不是可见的,只有在onResume的时候才会把View设置为可见,想了解清楚的可以查看 Window和WindowManager的创建与Activity
此时Activity进入前台,具备与用户交互的能力。与onStart()都是对用户可见,但是onStart()时Activity是位于后台的,onResume()时Activity才显示到前台。 如果我们在onPause()中释放了组件,我们应该在onResume()中重新初始化。 我们应该在这里开始动画和初始化一些只有用户关注时才使用的组件。
当用户离开了Activity时会回调这个方法,比如说:
我们可以在这个方法中执行一些释放资源的操作,比如broadcast receivers,sensors,以及一些用户在不交互时不需要的资源。
该方法执行的时间非常简短,因此不应该在这个方法保存程序或用户数据;在该方法完成之前,保存工作可能并未完成。而且会影响到新的Activity的显示,因为onPause()执行完,新Activity才会开始执行onCreate()。
当Activity对用户不再可见的时候会回调该方法,比如说启动一个新的Activity把屏幕全都遮住了。
之前说过不建议在onPause()做一些重量级的释放工作,应该交由onStop()去释放大多数资源。比如unregisterReceiver(),还有其他可能导致内存泄露的资源,因为系统可能在没有回调onDestroy()的时候就杀掉了进程。
在Activity被销毁之前会回调该方法,这也是Activity生命周期的最后一个回调。
如果在Activity调用了finish()或者由于内存紧张系统销毁了该Activity,也有可能是由于横竖屏的切换或者用户按了返回键都会导致该方法的回调,
我们应该在这个方法中回收之前没有回收掉的所有资源
ActivityA:onPause() -ActivityB:onCreate()-ActivityB:onStart()-ActivityB:onResume()- ActivityA:onStop()
当ActivityA调用完onPause()之后才会调用ActivityB的onCreate(),所以不要在onPause()中做耗时操作,会影响新Activity的显示。
只有当ActivityB的onResume()调用完之后才会调用ActivityA的onStop(),因为此时ActivityB在最上面,ActivityA才是完全不可见的。
onPause()-onSaveInstanceState()-onStop()-onDestroy()-onCreate()-onStart()-onRestoreInstanceState()-onResume()
如果没有在AndroidManifest设置configChanges,则屏幕旋转的时候会吧Activity销毁再重建,并且重建后的Activity和原来的不是同一个实例。
如果设置了android:configChanges="orientation|screenSize",则屏幕旋转时只会调用onConfigurationChanged()方法,并且不会销毁重建
首先每个应用最少有一个进程,我们的Activity都是运行在进程中的,当应用退到后台时,系统可能因为内存不足而杀掉优先级低的进程,那么再该进程中的Activity都会被杀死,这种情况是不会走Activity的生命周期的,只有杀掉单个Activity的时候才会走Activity的onDestroy()方法。
onPause()-onStop()-onDestroy()
当Activity弹出Dialog获取PopupWindow是不会走任何生命周期的。
弹出DialogActivity原来的Activity会执行onPause(),关闭DialogActivity原来的Activity执行onResume()
onPause()-onStop()-onRestart()-onStart()-onResume()
onPause()-onNewIntent()-onResume()
2Android之Activity全面解析,有些知识点容易忘记
Activity作为安卓四大组件之一,是最重要也是用得最多的组件,涉及的知识点非常多,有些知识点平时开发很少用到,但在某些场景下需要特别注意,本文详细整理了Activity涉及的知识点,供开发参考。
针对Activity可以提出很多问题,如:
Activity 的生命周期?
Activity 之间的通信方式?
Activity 各种情况下的生命周期?
横竖屏切换时 Activity 的生命周期?
前台切换到后台,然后再回到前台时 Activity 的生命周期?
弹出 Dialog 的时候按 Home 键时 Activity 的生命周期?
两个Activity之间跳转时的生命周期?
下拉状态栏时 Activity 的生命周期?
Activity 与 Fragment 之间生命周期比较?
Activity 的四种 LaunchMode(启动模式)的区别?
Activity 状态保存与恢复?
Activity的转场动画有哪些实现方式?
Activity的生命周期中怎么获取控件宽高?
onNewIntent的执行时机?
如何连续退出多个Activity?
如何把Acitivty设置成Dialog样式 ,android:theme="@android:style/Theme.Dialog"
关于横竖屏切换的生命周期,对应不同的手机,由于厂商定制的原因,会有不同的效果,如设置了configChanges="orientation”在有些手机会执行各个生命周期,但有些手机却不会执行。
网上常见的结论如下:
但实际的测试如下:
可以看出,不同厂商的手机切屏生命周期会有差异。
从API 13以上,当设备在横竖切屏时,“屏幕尺寸”也会发生变化,因此为了杜绝切屏导致页面销毁重建,需要加上screenSize,使用设置4,即 android:configChanges="orientation|keyboardHidden|screenSize" .
Activity的四种状态如下:
在activity处于paused或者stoped状态下,如果系统内存紧张,可能会被销毁,当重回该activity时会重建,正常返回和被回收后返回的生命周期如下:
如果是回收后返回,onCreate的参数savedInstanceState不为空。
有哪些场景会触发onNewIntent回调呢?跟启动模式有关,首先该Activity实例已经存在,再次启动才可能触发。一种情况是启动模式是singleTask或者singleInstance,无论该activity在栈中哪个位置,都会触发onNewIntent回调,并且把上面其他acitivity移除,另一种情况是启动模式是singleTop或者以FLAG_ACTIVITY_SINGLE_TOP启动,并且该activity实例在栈顶,会触发onNewIntent,如果不在栈顶是重新创建的,不会触发。
在实际业务开发中,往往碰到需要连续退出多个activity实例,下面整理了几种常见方法:
● 发送特定广播
1、在需要处理连续退出的activity注册该特定广播;
2、发起退出的activity发送该特定广播;
3、接收到该广播的activity 调用finish结束页面。
● 递归退出
1、用startActivityForResult启动新的activity;
2、前一个页面finish时,触发onActvityResult回调,再根据requestCode和resultCode处理是否finish,达到递归退出的效果。
● FLAG_ACTIVITY_CLEAR_TOP
通过intent.setFlag(Intent.FLAG_ACTIVITY_CLEAR_TOP)启动新activity,如果栈中已经有该实例,则会把该activity之上的所有activity关闭,达到singleTop启动模式的效果。
● 自定义activity栈
1、自定义activity列表,新打开activity则加入栈中,关闭则移除栈;
2、需要退出多个activity时,则循环从栈中移除activity实例,并调用finish。
在讨论Activity启动模式经常提到任务栈,那到底什么是任务栈?
任务是一个Activity的集合,它使用栈的方式来管理其中的Activity,这个栈又被称为返回栈(back stack),栈中Activity的顺序就是按照它们被打开的顺序依次存放的。返回栈是一个典型的后进先出(last in, first out)的数据结构。下图通过时间线的方式非常清晰地向我们展示了多个Activity在返回栈当中的状态变化:
taskAffinity 任务相关性,可以用于指定一个Activity更加愿意依附于哪一个任务,在默认情况下,同一个应用程序中的所有Activity都具有相同的affinity, 名字为应用的包名。当然了,我们可以为每个 Activity 都单独指定 taskAffinity 属性(不与包名相同)。taskAffinity 属性主要和 singleTask 启动模式和 allowTaskReparenting 属性配对使用,在其他情况下没有意义。
taskAffinity 有下面两种应用场景:
分为显示启动和隐式启动。
(1)显示启动
直接指定待调整的Activity类名。
(2)隐式启动
Intent 能够匹配目标组件的 IntentFilter 中所设置的过滤信息,如果不匹配将无法启动目标 Activity。IntentFilter 的过滤信息有 action、category、data。
IntentFilter 需要注意的地方有以下:
● 一个 Activity 中可以有多个 intent-filter
● 一个 intent-filter 同时可以有多个 action、category、data
● 一个 Intent 只要能匹配任何一组 intent-filter 即可启动对应 Activity
● 新建的 Activity 必须加上以下这句,代表能够接收隐式调用
category android:name="android.intent.category.DEFAULT" /
只要匹配一个action即可跳转,注意的是action要区分大小写。
规则:如果intent中有category,则所有的都能匹配到intent-filter中的category,intent中的category数量可用少于intent-filter中的。另外,单独设置category是无法匹配activity的,因为category属性是一个执行Action的附加信息。
intent不添加category会匹配默认的,即 “android:intent.category.DEFAULT”
如果上面例子,如果去掉intent.setAction("action_name"),则会抛出异常:
规则:类似action,但data有复杂的结构,只要匹配一个data并且与data中所有属性都一致就能匹配到Activity,只要有1个属性不匹配,都无法找到activity。
data的结构:
data 主要是由 URI 和 mimeType 组成的。
URI 可配置很多信息,的结构如下:
与url类似,例如:
mineType:指资源类型包括文本、图片、音视频等等,例如:text/plain、 image/jpeg、video/* 等
下面看下data匹配的例子:
只匹配scheme
只匹配scheme也是能匹配到activity的。
匹配scheme、host、port
将上面的data改为
匹配mineType
如果有mineType,则不能仅设置setData或setMineType了,因为setData会把mineType置为null,而setMineType会把data置为null,导致永远无法匹配到activity,要使用setDataAndType。
使用scheme的默认值content\file
注意该方法需要在startAtivity方法或者是finish方法调用之后立即执行,不能延迟,但可以在子线程执行。
而在windowAnimationStyle中存在四种动画:
activityOpenEnterAnimation // 打开新的Activity并进入新的Activity展示的动画
activityOpenExitAnimation // 打开新的Activity并销毁之前的Activity展示的动画
activityCloseEnterAnimation //关闭当前Activity进入上一个Activity展示的动画
activityCloseExitAnimation // 关闭当前Activity时展示的动画
overridePendingTransition的方式比较生硬,方法也比较老旧了,不适用于MD风格,google提供了新的转场动画ActivityOptions,并提供了兼容包ActivityOptionsCompat。
我们知道在onCreate和onResume里面直接获取到控件宽高为0,那有什么办法获取到控件的实际宽高?只要有onWindowFocusChanged、view.post、ViewTreeObserver三种方式获取。
当用户点击桌面图标启动APP时,背后的流程如下:
我们看到的手机桌面是Launch程序的界面,点击应用图标会触发点击事件,调用startActivity(intent),然后通过Binder IPC机制,与ActivityManagerService(AMS)通讯,AMS执行一系列操作,最终启动目前应用,大概流程如下:
通过PackageManager的resolveIntent()收集跳转intent对象的指向信息,然后通过grantUriPermissionLocked()方法来验证用户是否有足够的权限去调用该intent对象指向的Activity。如果有权限,则在新的task中启动目标activity,如果发现没有进程,则先创建进程。
如果进程不存在,AMS会调用startProcessLocked创建新的进程,在该方法中,会通过socket的通讯方式通知zygote进程孵化新的进程并返回pid,在新的进程中会初始化ActivityThread,并依次调用Looper.prepareLoop()和Looper.loop()来开启消息循环。
创建好进程后下一步要将Application和进程绑定起来,AMS会调用上一节创建的ActivityThread对象的bindAppliction方法完成绑定工作,该方法会发送一条BIND_APPLICATION的消息,最终会调用handleBindApplication方法处理消息,并调用makeApplication方法处理消息,加载APP的classes到内存中。
通过前面的步骤,系统已经拥有了该Application的进程,后续的启动则是从已存在其他进程中启动Acitivity,即调用realStartAcitvityLocked,该方法会调用Application的主线程对象ActivityThread的sheduleLaunchActivity方法,在方法中会发送LAUNCH_ACTIVITY到消息队列,最终通过handleLaunchActivity处理消息,完成Acitivty的启动。
Activity
Activity 的 36 大难点,你会几个?「建议收藏」
[译]Android Application启动流程分析
3Activity的生命周期
在Activity生命周期中,系统调用App生命周期中设置的回调方法,这些生命周期回调方法在第一层就像一个金字塔。活动生命周期的每个阶段都对应于金字塔的一个步骤。
当系统创建一个新的Activity实例时,回调方法从塔的底部一级一级地移动到塔的顶部。当它位于金字塔的顶部时,活动位于用户的前台,此时用户可以与活动进行交互。当用户想要离开活动时,系统调用另一系列方法将活动的状态从顶部移到底部。在某些情况下,Activity只完成部分状态迁移并等待用户的指令,然后返回到塔顶。
根据活动的复杂性,您可能不必实现所有的生命周期方法。但是,理解每个生命周期回调函数的含义非常重要,以确保您的应用程序按照用户的期望正确运行。
要正确实现生命周期的回调方法,从而使应用程序正确动作,需要注意以下几点:
确保用户使用你时,应用程序可以接听电话或切换到其他应用程序,而不会崩溃。确保您的应用程序在用户不使用时不会消耗系统资源。
确保用户在从其他应用程序切换回您的应用程序时可以继续他们以前的工作,并且在切换用户屏幕或其他操作时不会崩溃或丢失用户数据。
4Activity与Fragment的生命周期详解
一.Activity的生命周期
首先我们来看一下官方文档中给出的图示:
通过上述图示,我们可以总结Activity的生命周期规律如下:
1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。
2.当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。
5.用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。
6.当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
7.用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。
注意onPause与onStop的不同,onPause表示该Activity处于可见状态但无法获取用户焦点,如在当前Activity上弹出一个对话框,则用户焦点被对话框获取,但当前Activity仍然可以看到,而onStop表示该Activity处于不可见状态,如从一个Activity跳转到另一个Activity,则之前的Activity处于不可见状态。
二Fragment的生命周期
还是先上官方文档图:
从上述图示可以看到Fragment与Activity的生命周期极其相似,我们先看一下只存在于Fragment中的几个方法:
onAttach方法:顾名思义,是Fragment和Activity建立关联的时候调用。
onCreateView方法:为Fragment加载布局时调用。
onActivityCreated方法:当Activity中的onCreate方法执行完后调用。
onDestroyView方法:Fragment中的布局被移除时调用。
onDetach方法:顾名思义,是Fragment和Activity解除关联的时候调用。
重点注意一下onActivityCreated(),因为该方法是在Activity中的onCreate方法执行完成后调用,所以在onActivityCreated()调用之前 Activity的onCreate可能还没执行,所以不能在onCreateView()中进行 与Activity相关的UI操作,而应该在onActivityCreated()中进行与Activity相关的UI操作,而onCreateView中只进行UI的显示操作。
另外需要注意Fragment中不存在onRestart()方法,该方法只存在与Activity中。
5android的生命周期
单个Actiivty正常的生命周期
onCreate - onStart - onResume - onPause - onStop - onDestory
这就是一个Activity从被创建到被销毁过程。
其中正常运行状态为onResume
当Activity从前台被置于后台,
onResume - onPause - onStop
当从后台重新置于前台
onStop - onPause - onResatrt - onStart- onResume
其中可以发现,只要Activity置于前台都会执行onStart函数,所以我们可以考虑在这里做一下需要在前台就处理的逻辑
各个生命周期函数:
onCreate: Activity被创建,此时Activity处于不可见、不可交互
onStart: 此时Activity 部分可见不可交互
onRestart: Activity从后台重新回到前台,部分可见不可交互
onResume: 完全可见可交互,为Activity正常运行状态
onPause: Activity处于暂停,从前台被置于后台 部分可见部分不可见,不可交互
onStop: 完全置于后台,完全不可见,
onDestroy: Activity被销毁
上面就是一个正常的Activity的生命周期,
在Activity生命周期中,还设计一些其他:
Activity旋转:
onCreate - onStart - onResume
此时被旋转
- onPause - onSaveInstanceState - onStop - onDestroy - onCreate - onStart - onRestoreInstanceState - onResume
可以发现当Activity被旋转时,整个Activity是被销毁然后重新创建的。其中新增调用了两个生命周期函数
onSaveInstanceState: 当Activity被系统异常销毁时被调用,用于存储数据,用于系统恢复Activity时恢复数据
onRestoreInstanceState: 当Actiivty被系统异常销毁并重新创建时,取出在onSaveInstanceState时存储的数据
注意,在onCreate函数中,其实也是有参数的
此处的savedInstanceState也是在onSaveInstanceState时存储的数据,但此处可能为nll,
因为在正常的Activity时,此处就是null,只有在Activity被异常销毁然后被系统重新创建时,此处才有值。
如果要在此处使用,切记要判空。
onNewIntent与Activity的启动模式有关
当Activity未设置启动模式时,则不会触发该生命周期函数
当Activity已经处于应用的Activity栈中
onNewIntent只会在Activity设置了启动模式,并且Activity被复用时才会调起。
注意:只对startActivityForResult调起的Activity起作用,statActivity本质调用的也是startActivityForResult,Activity正常的切换前后台时不会触发的。
A - B:
A正常运行处于 onResume,打开B
A onPause - B onCreate - B onStart - B onResume - A onStop
点击跳入B页面, 首先A进入暂停,B开始创建,到onResume完全可见可交互,于是A被完全遮挡,变成完全不可见、处于后台,进入onStop
A - B -goBack- A
在B页再执行返回
B onPause - A onRestart - A onStart - A onResume - B Stop - B onDestory
和A进入B类似,B返回A时,B进入暂停,A变得重新可见到A完全可见,进入onResume,然后B进入停止,并销毁
B启动模式设置为 SingleTop,B - B
B onPause - B onNewIntent - B onResume
因为 B已经处于栈顶,启动模式为 SingleTop 则不会重新创建B的实例
将A的启动模式设置为SingleTask
可以通过在andorid studio的终端 Terminal中输入:adb shell dumpsys activity
查看当前应用的Activity task栈
6Android Activity生命周期解析
Activity 用户可以做单一的、集中的事情。几乎所有的Activity都与用户进行交互,所以Activity类负责创建一个窗口,你可以通过调用setContentView(View)把你的UI布局放置在Activity的窗口中。作为四大组件之一,使用频率非常高。深入了解Activity,对于我们高质量开发是很有帮助的,下面我们就来看看Activity的生命周期。
Android系统中是通过Activity栈的方式来管理Activity的,而Activity自身则是通过生命周期的方法来管理的自己的创建与销毁。那么我们就来看看Activity生命周期是怎样运作的。
周期即活动从开始到结束所经历的各种状态。生命周期即活动从开始到结束所经历的各个状态。从一个状态到另一个状态的转变,从无到有再到无,这样一个过程中所经历的状态就叫做生命周期。
Acitivity本质上有四种状态:
在上面的四中常有的状态之间,还有着其他的生命周期来作为不同状态之间的过度,用于在不同的状态之间进行转换。
我们先来看看下面这张经典的生命周期流程图:
1)启动Activity
onCreate() — onStart() — onResume()
2)按Home键回到桌面 / 锁屏
onPause() — onStop()
3)从桌面回到Activity / 解锁
onRestart() — onStart() — onResume()
4)跳转新Activity
A: onPause() — onStop()
B: onCreate() — onStart() — onResume()
A — B: onPause()_A — onCreate()_B — onStart()_B — onResume()_B — onStop()_A
5)返回上一个Activity
B: onPause() — onStop() — onDestroy()
A: onRestart() — onStart() — onResume()
B — A: onPause()_B — onRestart()_A — onStart()_A — onResume()_A — onStop()_B — onDestroy()_B
6)退出Activity
onPause() — onStop() — onDestroy()
Activity官方文档,开启传送门
至此Activity的整个生命周期都介绍完了,现在我们再看之前的生命周期流程图,是不是清晰许多。搞清楚Activity活动原理,这样理解起来就会容易许多,工作中也能如鱼得水。
END,本文到此结束,如果可以帮助到大家,还望关注本站哦!