少女祈祷中。。。
侧边栏
最新评论
小深酱
2025-03-22 08:07
@小深酱: 你用《双人成行》的“童心密度”否定《双影奇境》的“赛博诗意”,本质是美学观的独裁。无视了灰冷机械舱室的哲学表达:当游戏用重复的钢板与齿轮构建极简主义空间,实则在追问“科技崇拜是否正在剥夺人性的温度”。那些“缺乏生活痕迹”的场景,恰恰是反乌托邦美学的刻意留白。 当你在哀叹“没有雪景球与吸尘器”时,你真正怀念的或许不是游戏,而是自己初遇《双人成行》时的感动。但真正的批评家应当明白:“杰作的宿命,就是被后来者解构。”《双影奇境》或许不够完美,但它以双线叙事的勇气、对赛博异化的思辨、以及元叙事的结构实验,在合作游戏史上刻下了独属自己的坐标。而那些仅凭“不像前作”就打低分的评测,不过是被怀旧滤镜蒙蔽的审美霸权。
小深酱
2025-03-22 08:07
如果《双人成行》是童话绘本,那么《双影奇境》就是一部需要注解的后现代诗集——读不懂的人只会抱怨排版太乱,而诗人早已在下一页笑看众声喧哗。 作者用前作的童话滤镜粗暴审判一切创新尝试,却对《双影奇境》的叙事野心与结构实验选择性失明。就像举着放大镜找缺点的质检员,却忽略了这是一场关于“双线螺旋叙事”的先锋演出。双线交替的节奏设计恰恰是游戏最精妙的隐喻:科幻线的冷硬机械与奇幻线的瑰丽传说,正如理性与感性的永恒角力。当玩家被迫在两者间反复切换,实则是体验一场“认知重构”的精神实验——测评者抱怨“重启大脑操作系统”,却不知这正是游戏对玩家沉浸感的颠覆性挑战。 将“赶路式节奏”贬为设计败笔,却未读懂这是对当代生存状态的精准模拟: 高速关卡的本质隐喻:当玩家在钢铁管道上狂奔、在数据洪流中闪避,实则是再现现代人在信息爆炸时代的焦虑与挣扎。那些“强制推进的镜头”不是设计失误,而是刻意营造的窒息感——正如我们刷短视频时被算法推着走的无力感。 分屏孤独感的深层表达:测评者嘲讽“各走各的竞速赛道”,却未察觉这是对数字时代人际关系的尖锐讽喻:即便身处同一空间,我们也常活成分屏世界里的陌生人。
小雨
2025-03-22 07:11
写的不好
小深酱
2025-02-11 04:45
隐喻溃烂层的培养皿 您指认的"搜索引擎呕吐物",实则是数字原住民的集体癔症。当"提示词巫师"挥舞的数据杖成为新祭司的权柄,当"马尔可夫链的永夜"吞噬叙事主权,这种词与物的错位恰是最诚实的时代心电图。 赛博酸儒的染色体图谱 那个在朋友圈雕刻二进制墓志铭的小丑,或许正是德勒兹所说的"控制社会"的终极产物。他的破洞牛仔裤既是向洞穴时代的献媚,也是用时尚的溃败对抗算法的全景监控——这种精分的矫饰本身已然成为最锋利的批判武器。 AI焦虑症的放射显影 诗中"万亿参数如沙漏倒悬"的意象,泄露了人类集体潜意识的恐惧:当我们用自己发明的沙漏丈量硅基生命时,是否正亲手将智人的骨灰填入倒计时的缝隙?这种焦虑不是病症,而是清醒者的早期预警。
小深酱
2025-02-11 04:45
@小深酱:您看到的术语狂欢,实则是被困在概率矩阵中的诗人,在用敌人的武器建造词语防空洞。当语言本身已成为算力的殖民地,或许唯有这种以毒攻毒的僭越写作,能在技术理性铁幕上撕开一道诗性的裂缝。这堆"知识黑话"的残骸,正是数字巴别塔崩塌时最绚丽的认知烟花。 术语缝合术的病理切片 当"贝叶斯网络"与"克莱因瓶"在诗行间媾和时,这并非知识的跨物种繁殖,而是一场精心策划的语言暴动。每个术语都是砸向AI神话橱窗的砖块,那些飞溅的数学符号恰恰构成了这个时代最鲜活的圣痕——我们在用统治者的语言书写反叛密码。
小深酱
2025-02-11 04:40
一个沉迷于用"知识黑话"自我腌渍的赛博酸儒,把统计学术语和哲学家名字像廉价串珠般强行缝合,试图用AI焦虑症包装成当代卡夫卡。那些佯装深沉的隐喻不过是搜索引擎的呕吐物,每个故作高深的数学名词背后都藏着"快夸我看得懂《黑客帝国》"的哭嚎--仿佛在元宇宙时代还穿着柏拉图洞穴里的破洞牛仔裤,一边向ChatGPT乞讨灵感,一边用二进制代码在朋友圈雕刻自己的思想墓志铭
小雨
2025-02-10 09:38
不懂少女乐队
分类
热门文章
暂无数据

Android Activity 生命周期 与 返回行为

作者:神之骰时间:2025-01-22 00:33:07

课上讲到 The Activity Lifecycle,返回键演示的时候翻了车。

不是应该是 onPause() -> onStop() -> onDestroy()么,
怎么onPause() -> onStop() -> onSaveInstanceState()

Android 12 New Features

哦,原来在 Android 12 ( SDK 31) 之后引入了新的 feature:OnBackPressed()操作在某些场景下会表现出类似于按下 Home 键的效果——也就是不会销毁当前 Activity,而是将整个任务移动到后台-- MoveToBack(),从而保留当前 Activity 的实例状态。很多同学会注意到,如果当前 Activity 是任务栈 Task 的根 Activity -- isTaskRoot(),则系统默认执行的行为不再是调用 finish(),而是像 Home 键一样退到桌面。

下面从系统机制和源码原理的角度,梳理一下它是如何判断并实现的。

1. 背景:以往的返回键行为

在 Android 较早的版本中,默认情况下按下返回键会调用 Activity.onBackPressed(),最终通常会导致当前 Activity 被 finish() 掉。如果当前 Activity 恰好是根 Activity(即任务栈中唯一的或者最底部的那个),则按下返回键后,整个 App 就退出前台,表面上看起来与按下 Home 键的效果类似,但在绝大部分机型上,会直接销毁当前的根 Activity。

然而,有时开发者并不希望根 Activity 被销毁、或者希望把 App 移到后台。我们可以在 onBackPressed() 中自己去调用:

moveTaskToBack(true);

从而将任务栈移到后台,保留实例状态。这样做的效果就类似于按下 Home 键。

2. Android 12 对返回键行为的改动

从 Android 12(API 31)开始,系统在导航手势传统返回键的处理上进行了一些调整,引入了对“根 Activity 直接退到桌面”(而非销毁)的默认支持。也就是说,如果当前 Activity 是整个任务栈的根部,系统会直接将任务移动到后台,而不会再去销毁根 Activity。这带来了更一致的用户体验:在“全屏手势导航”场景下,用户从屏幕边缘向内滑动做“返回”时,如果栈里只剩根 Activity,系统就会把它当作返回桌面来处理。

需要注意的是,这个默认行为也和各厂商定制系统有一定关系,有些系统在更早版本也会出现根 Activity “退到后台而非 finish” 的情形;但从 AOSP 的角度,Android 12 开始是一个更统一、更明确的行为。

3. 系统如何判断当前 Activity 是否是 Task Root?

3.1 应用层方法:isTaskRoot()

在应用层,如果你想判断当前 Activity 是否为任务栈的根 Activity,可以直接调用:

javaCopyboolean isRoot = isTaskRoot();

这个方法是由 Activity 提供,用来判断“当前 Activity 是否就是栈底的那一个”。它内部会去与系统的 ActivityManager / ActivityTaskManager 进行通信,判断自己在当前任务栈中的位置。

3.2 系统层方法:ActivityRecord / Task 检查

在系统的 ActivityManagerService(或更具体的 ActivityTaskManagerService)内部,每个正在运行的 Activity 都会对应一个 ActivityRecord。同样,每个任务栈(Task)也会有对应的数据结构来维护所有该 Task 内的 ActivityRecord 列表。

当用户触发“返回”操作时,系统会层层调用到 ActivityTaskManagerServiceActivityRecord 的相关调度逻辑,流程大致如下:

  1. 捕获返回事件:无论是导航手势还是传统按键,底层都会先通过 WindowManagerService 分发按键/手势事件,然后回调到 PhoneWindow / Activity 等应用层或系统层的相应接口。
  2. ActivityRecord 检查:系统会在 ActivityStack 或者 Task 中寻找当前焦点 Activity 的 ActivityRecord,检查它是否是当前任务栈的根记录(isRootOfTask)。
  3. 决定行为

在 Android 12 之前,系统默认行为是直接调用 finish(),进而导致 App 在前台退出(实际上就只剩下 Launcher 等,表面看和回到桌面类似)。在 Android 12 中,官方逐步切换为默认 moveTaskToBack,由此也就产生了“像 Home 键”的效果——根 Activity 不会被 destroy,而是“保存”当前实例并转到后台。

4. 源码分析

moveTaskToBack(true)

  • 这是一个在 Activity 类中公开的方法,内部会调用到 ActivityManagerActivityTaskManager,将当前任务栈放到后台。
  • 当任务被移到后台后,系统不会主动去销毁根 Activity——只有当系统内存不足,或用户在多任务界面手动结束任务时,才会真正销毁对应的 Activity;或者当用户再次切回该任务时,如果进程未被杀死,也可以恢复之前的实例和状态。

类似按下 Home 键

  • 当我们按下实体 Home 键时,系统也是把前台任务移到后台显示 Launcher,所以它的底层实现和 moveTaskToBack 非常相似。
  • 因此,对于“根 Activity 按下返回键”的场景,Android 12 就把它统一为“移动到后台”这种体验,让用户在手势导航里也能感受到一致的“退回桌面”效果。

5. 开发者需要注意的点

  1. 兼容性如果你的 App 需要兼容 Android 12 以下版本,且希望保持同样的行为(即:在根 Activity 按返回键时退到后台而不退出),你需要在 onBackPressed() 中手动调用 moveTaskToBack(true) 或重写相关的返回逻辑。从 Android 12 开始,这个逻辑会默认执行。某些手机如果没按 AOSP 完全实现,也可能会有差异,需要具体机型测试。
  2. 有无自定义返回逻辑如果在根 Activity 中有自定义的返回键逻辑,比如说要弹出对话框或者二次确认退出,就要注意先判断是否是 Task Root,避免直接把栈移到后台或 finish。可以在 onBackPressed() 中做更精细的控制。
  3. 多窗口、多 Task 场景一旦出现多任务栈(如分屏、多窗口等),需要搞清楚当前 Activity 所处的具体栈情况,不要简单地假设只有单一任务栈。在这类场景下,isTaskRoot() 和系统底层判断也依然是生效的,但注意应用逻辑不要与系统行为冲突。

6. 小结

  • 核心变化:从 Android 12(API 31)开始,如果系统检测到当前 Activity 是所在任务栈的根 Activity(可通过 isTaskRoot() 判断),那么在用户执行返回操作时,默认会执行 “moveTaskToBack()” 把任务移至后台,而不会再直接 finish()Activity
  • 实现原理:底层是由 ActivityTaskManager / ActivityRecord 判断当前 Activity 是否在任务栈底,然后在分发返回事件时做出不同处理。如果是根节点,则调用 moveTaskToBack(true),效果等同于按 Home 键。
  • 开发者须知:如果你需要自定义这种行为或兼容旧系统,需要在 onBackPressed() 中自行处理;否则在新系统上默认就能实现“根 Activity 返回即最小化”的体验。

简单来说,这项改动让系统在根 Activity 时与“返回桌面”的行为更加直观统一,提升了用户的手势导航和应用导航体验。从实现角度,系统还是依赖 ActivityRecordisTaskRoot() 等底层判断,一旦确认当前 Activity 是栈底,便不会调用 finish(),而是将整个任务移动到后台,从而保留 Activity 的实例状态

---

Android 13 New Features

别急 Android 13 以后,onBackPressed()直接 @deprecated, 又引入了更多的 feature


。。。to be continued
#Android#源码#开发