Ⅰ android activity 按back键 执行什么过程
进程只是一个APP的容器,容器内的内容不会因为容器的空置而消失。但一旦容器被销毁,容器中的内容也会随之销毁。当用户按下back键时,实际上是执行了一个栈操作,具体来说就是栈顶元素被移除(即弹出,英文称为pop操作)。这一过程会触发栈顶Activity的onBackPressed()方法,默认情况下,这个方法会调用finish(),finish()方法则会进一步调用Activity的onDestroy()方法,从而销毁当前Activity。
而当用户按下home键时,系统的处理方式则是将整个任务栈挂起并放到后台,使用户回到启动器首页。此时,Activity并未被销毁,因此不会触发Activity的onDestroy()方法。至于长按home键启动任务管理器来结束应用,这种情况下,进程的存在与否则取决于具体的手机型号。一些手机可能会销毁应用(即销毁Application类的实例),但进程作为容器仍然存在,只是其中的内容为空。如果发现进程消失,通常是因为系统回收了空进程。而在另一些手机上,直接结束进程的操作可能会导致整个进程被彻底销毁。
综上所述,按下back键和home键的不同处理方式,导致了两种不同的结果:一种是销毁当前Activity并调用其生命周期方法;另一种则是简单地挂起任务栈并将其移至后台,仅在用户再次启动应用时才会重新加载。
需要注意的是,进程的空置并不意味着其完全消失,这与进程的生命周期管理紧密相关。在某些情况下,即使应用未运行,其对应的进程也可能仍然存在于后台,等待下次需要时被重新激活。
Ⅱ Intent#FLAG_ACTIVITY_CLEAR_TOP 真的会 clear top 吗
前几天,处理了一个App内草稿丢失的用户反馈。许多用户反映在连续保存多个草稿后,草稿箱中只有一个草稿,这显然是发生了草稿丢失的情况。通过分析用户反馈的数据,发现他们的系统版本都在Android 7.0以下。
经过一段时间的调查,最终发现是草稿被覆盖了,原因是在保存草稿后,录制页、编辑页、发布页等链路页面没有被关闭,再次进入录制环节时录制页复用了状态,导致保存草稿时发生了草稿替换。那么,问题就来了,为什么会发生这样的情况呢?这需要从保存草稿那一刻说起。
在发现问题时,我们注意到,在正常情况下,保存草稿后会关闭录制链路上的活动,这通常通过Intent#FLAG_ACTIVITY_CLEAR_TOP | Intent#FLAG_ACTIVITY_NEW_TASK来实现。从代码逻辑来看,这包括在Intent中添加clear_top标志,并设置跳转到首页。这里的返回的是MainActivity,从表面上看没有问题。
然而,在尝试在小米10 Pro上进行测试时,保存草稿后没有出现复现问题的情况。回到首页并按下返回键后,直接退出了App。这表明录制链路页面被关闭了。在更换多台手机后,终于在一台Android 5.1设备上成功复现了这种情况,发现保存草稿并返回首页时,再次按下返回键会回到发布页,录制链路依然存在。
核心问题在于:为什么在Android 5.1设备上clear_top这个标志没有生效?
关于Intent#FLAG_ACTIVITY_CLEAR_TOP,其主要功能是:在目标活动已经存在时,将目标活动所在的任务移动到前台,然后结束目标活动上层的所有活动,并最终打开目标活动。不过,Intent#FLAG_ACTIVITY_CLEAR_TOP如何判断目标活动已经存在这一点,在注释中并未详细说明。
回到我们的工程中。一般情况下,首页、录制页、编辑页、发布页处于同一个任务堆栈中,通过adb打印的活动堆栈信息也可以确认这一点。
adb shell mpsys activity activities | grep 'com.liaoapp.musically'
通过查看这几个活动的启动模式,并没有发现任何不同之处:VideoRecordNewActivity: singleTask VideoPublishEditActivity: standard(default) VideoPublishActivity: singleTask
这里我们大胆猜测,不同版本的ROM对Intent#FLAG_ACTIVITY_CLEAR_TOP的处理可能有差异,导致这个标志没有生效。
为了验证这个假设,我们创建了一个Demo工程,构建了A、B、C三个空页面,分别对应首页、录制页、发布页,跳转路径为:A -> B -> C -> A。其中A、B、C的启动模式分别为singleTop, singleTask, singleTask,与App内的录制链路一致。
在测试中,我们发现C使用clear_top回到A后,并没有将B和C关闭掉。这让我们怀疑是否是App内部对Activity或Intent的处理方式有误。进一步分析发现,在Android 5.1测试机上运行时,保存草稿后任务栈并没有被清理,这让我们怀疑是否是ROM的问题。在模拟器上运行测试,也出现了同样的情况,这让我们开始怀疑是否是Android的Bug。
在对代码进行深入分析后,我们发现是由于SplashActivity作为启动Activity,被声明为activity-alias,其targetActivity指向了MainActivity。在AndroidManifest中查看SplashActivity和MainActivity的声明时,我们发现SplashActivity被声明为了activity-alias,其targetActivity指向了MainActivity。
为了解决这个问题,我们修改了Demo工程,添加了Splash页面,并将其声明为activity-alias。现在Demo的启动流程变成了:Splash -> A -> B -> C -> A。在修改后再次进行测试,结果在Android 5.1测试机上确实复现了问题,即C使用clear_top打开A后,并没有将B和C关闭掉。这进一步验证了是由于activity-alias的存在导致了clear_top标志没有生效。
最终,我们发现是由于活动启动流程中对Intent#FLAG_ACTIVITY_CLEAR_TOP标志的处理存在差异,导致在Android 5.1设备上该标志没有生效。通过对活动记录、任务记录和任务栈的深入分析,我们发现Android 6.0及以下版本和Android 7.0及以上版本在处理clear_top标志时存在差异。Android 7.0及以上版本在启动流程中对ActivityRecord#realActivity进行了调整,使得在启动活动时,如果目标活动是某个activity-alias的targetActivity,那么在处理clear_top标志时能够正确地结束目标活动上层的所有活动。
通过这个分析,我们了解到Intent#FLAG_ACTIVITY_CLEAR_TOP确实会清空顶部活动,但在不同的Android版本中,其行为可能会有所不同。解决这个问题的关键在于确保在启动链路中正确处理activity-alias和明确指定目标活动的targetActivity,以确保在需要时clear_top标志能够生效。
Ⅲ Activity的几种启动模式
一.先理解栈的概念(放置Activity实例的容器)
1.Task(线性表)
任务栈Task,用来放置Activity实例的容器,先进后出,主要有2个基本操作:压栈和出栈,其所存放的Activity是不支持重新排序的, 只能根据压栈和出栈操作更改Activity的顺序 。
2.app启动时,系统会为它默认创建一个对应的Task,用来放置根Activity
ps: Activity之间可以相互启动,当前应用的Activity可以去启动其他应用的Activity(相机),那么就是说栈的功能可以把其它app的activity加入到自己app的栈里.
所以Task可以理解为负责管理所有用到的Activity实例的栈,但是.android5.0之后 跨进程调用activity,这个activity会被放入到一个新的栈中。
二.启动模式(只能根据压栈和出栈操作更改Activity的顺序,所以是启动模式是以哪种姿势入栈)
通过在AndroidManifest文件中的属性andorid:launchMode来设置或者通过Intent的flag来设置
1.standard(常规姿势入栈)
默认模式。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。应用场景:绝大多数Activity。
2.singleTop(栈顶复用姿势入栈)==FLAG_ACTIVITY_SINGLE_TOP
栈顶复用模式,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,而是调用 onNewIntent() 方法。避免栈顶的activity被重复的创建。应用场景:在通知栏点击收到的通知,然后需要启动一个Activity,这个Activity就可以用singleTop,否则每次点击都会新建一个Activity。某个场景下连续快速点击,启动了两个Activity。如果这个时候待启动的Activity使用 singleTop模式也是可以避免这个Bug的。
3.singleTask(栈内复用姿势入栈)==FLAG_ACTIVITY_CLEAR_TOP
栈内复用模式, activity只会在任务栈里面存在一个实例。如果要激活的activity,在任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity,调用 onNewIntent() 方法,并且清空这个activity任务栈上面所有的activity( CLEAR_TOP回到栈顶 )。应用场景:大多数App的主页。对于大部分应用,当我们在主界面点击回退按钮的时候都是退出应用,那么当我们第一次进入主界面之后,主界面位于栈底,以后不管我们打开了多少个Activity,只要我们再次回到主界面,都应该使用将主界面Activity上所有的Activity移除的方式来让主界面Activity处于栈顶,而不是往栈顶新加一个主界面Activity的实例,通过这种方式能够保证退出应用时所有的Activity都能报销毁。
4.singleInstance(不入栈)
单一实例模式,整个手机操作系统里面只有一个实例存在。不同的应用去打开这个activity 共享公用的同一个activity。他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。应用场景:呼叫来电界面。这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。建议谨慎使用。
5.FLAG_ACTIVITY_NO_HISTORY
Activity使用这种模式启动Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保留在Activity栈中。
1.getTaskId();获取当前activity所处的栈
2.同一个应用程序中的activity的亲和性一样(taskAffinity),也就是说 Actviitya intent时setFalg(Intent.FLAG_ACTIVITY_NEW_TASK)到Activityb 但是Actviitya和Activityb 还是一个栈
在不同的应用中跳转才会创建新的Task。
3.在Activity上下文之外启动Activity需要给Intent设置FLAG_ACTIVITY_NEW_TASK标志,不然会报异常。
四 FLAG_ACTIVITY_CLEAR_TASK(必须和FLAG_ACTIVITY_NEW_TASK一起使用)
清空栈内activity,只留下这个activity
Ⅳ ActivityManager是什么如何高效使用
ActivityManager是Android系统中的一个核心服务,负责管理应用程序的生命周期和任务堆栈,确保应用程序在后台运行时不会占用过多资源,同时为用户提供流畅的操作体验。以下是关于ActivityManager的详细介绍以及如何高效使用它的方法:
一、ActivityManager的主要功能
二、如何高效使用ActivityManager
合理使用Activity生命周期方法
优化任务堆栈
管理内存
利用ActivityManager提供的API
综上所述,高效使用ActivityManager需要开发者深入理解其功能和API,并结合实际应用场景进行合理的优化和管理。