[Android Training视频系列]2.4 Recreating an Activity

本文深入解析Android应用中activity被销毁时如何保存状态及重启时如何恢复状态,包括使用onSaveInstanceState与onRestoreInstanceState方法的实践与注意事项。
1.主要内容
本讲讲解onSaveInstanceState与onRestoreInstanceState的使用。

2.视频讲解

http://www.eyeandroid.com/thread-11391-1-1.html

3.翻译参考
存在一些情况,由于普通的程序行为,你的activity会被销毁,比如,当用户点击Back按钮,或者自己调用finish()方法。另外,如果activity被停止了并且很久没被使用,或者前台的系统需要更多的资源,系统也可能会销毁你的activity。

当你的activity是因为按Back键或者自己结束的,那么系统认为这个activity实例已经是不需要了,因为你的行为明确指出了你要销毁它。然而,如果系统是强制销毁你的activity的话,虽然activity实例已经没有了,不过系统能够记住它的存在,当用户从新回到这个程序时,系统会使用activity被销毁时保存的状态重新创建一个activity实例。这个系统用来恢复先前状态的保存数据被称为“实例状态”,是一些key-value的集合保存在Bundle对象中。

警告:当用户旋转屏幕时,你的activity会被销毁并且重新创建。因为屏幕配置已经改变,你的activity可能也需要加载另外一些可选择的资源(比如 布局)。

默认情况下,系统使用Bundle实例状态保存布局中每个View对象的信息(比如EditText对象中的文本值)。所以,如果你的activity对象被销毁和重新创建时,布局状态会重新恢复到先前的状态。不管怎样,你的activity可能有很多需要恢复的状态信息,比如追踪用户进程的成员变量。

为了你能够保存一些额外的数据到实例状态中,这里提供了一个额外的生命周期回调函数,它没有在前面课程的图例中显示出来。这个函数叫onSaveInstanceState(),当用户离开activity时系统会调用它。当你的activity被意外销毁时,系统会调用这个函数,函数的Bundle对象会被保存下来,所以你可以添加额外的信息给这个Bundle。然后,如果系统必须重启这个被销毁的activity,它就传递相同的Bundle对象给activity的onRestoreInstanceState()方法和onCreate()方法。
basic-lifecycle-savestate.png
图解:当系统开始停止你的activity,它呼叫onSaveInstanceState()(1)方法,因此你可以保存指定的附加状态数据。如果activity被销毁了,然后相同的实例要被重新创建,系统传递定义在(1)的状态给onCreate()(2)和onRestoreInsatanceState()(3)。

保存你的activity状态

当你的activity开始停止,系统就调用onSaveInstanceState(),你可以在这个函数中使用key-value对的集合保存信息。默认函数实现了保存activity的view状态,比如EditText的文本,或者ListView的滚动条位置。

为了保存附加信息,你必须实现onSaveInstanceState()方法,添加key-value对到Bundle对象中,例如:
  1. static final String STATE_SCORE = "playerScore";  
  2. static final String STATE_LEVEL = "playerLevel";  
  3. ...  
  4.   
  5. @Override  
  6. public void onSaveInstanceState(Bundle savedInstanceState) {  
  7.     // 保存用户当前游戏状态  
  8.     savedInstanceState.putInt(STATE_SCORE, mCurrentScore);  
  9.     savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);  
  10.       
  11.     // 通常调用父类,让他能保存View的信息。  
  12.     super.onSaveInstanceState(savedInstanceState);  
  13. }  

警告:通常需要在onSaveInstanceState()实现中调用它的父类方法,以便能够实现保存view的信息。

恢复你的activity状态

如果你的activity在它被销毁后重启,你可以从系统传递给你的Bundle中恢复保存的状态,onCreate()和onRestoreInstanceState()都可以接受到相同的包含实例状态信息的Bundle。

因为onCreate()函数在系统创建一个新的activity实例或者重新创建前一个activity时都会调用,所以你必须在读取Bundle前检查它是否为空,如果是空的,那么系统是创建一个新的实例,如果不是,那么就恢复前一个被销毁的activity。

例如,这里是onCreate()方法中实现恢复数据:
  1. @Override  
  2. protected void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState); // Always call the superclass first  
  4.      
  5.     // 检查是否是一个前面销毁的activity实例。  
  6.     if (savedInstanceState != null) {  
  7.         // 恢复玩家状态  
  8.         mCurrentScore = savedInstanceState.getInt(STATE_SCORE);  
  9.         mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);  
  10.     } else {  
  11.         // 为新实例初始化一个默认值  
  12.     }  
  13.     ...  
  14. }  

你也可以选择在onRestoreInstranceState()方法中实现,当系统调用完onStart()函数后会调用onRestoreInstranceState(),不过仅仅是当有状态需要恢复时才会调用,所以你不需要检查Bundle是否为空:
  1. public void onRestoreInstanceState(Bundle savedInstanceState) {  
  2.     // 调用父类恢复默认的View的状态  
  3.     super.onRestoreInstanceState(savedInstanceState);  
  4.      
  5.     // 恢复玩家状态  
  6.     mCurrentScore = savedInstanceState.getInt(STATE_SCORE);  
  7.     mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);  
  8. }  

警告: 通常需要调用onRestoreInstanceState()的父类方法,以便能恢复默认的视图状态。

学习更多在运行中重建activity(比如屏幕旋转)的知识,可以看这里: Handling Runtime Changes .






<think>好的,我现在需要回答用户关于Android手机暗色模式设置后会触发哪些日志的问题。首先,用户之前询问过暗色模式日志查看的方法,现在他们想了解在Android设备上开启暗色模式时,系统或应用会产生哪些日志。 首先,我应该回顾一下Android的暗色模式是如何工作的。暗色模式(Dark Mode)在Android 10(API 29)及更高版本中作为系统级功能引入,允许用户全局启用深色主题。当用户切换暗色模式时,系统会发送配置变更事件,应用需要响应这些变化以调整主题。 接下来,我需要确定哪些日志会被触发。通常,日志可能来自系统层面和应用层面。系统层面可能有设置变化的记录,而应用层面则会有主题切换相关的日志。此外,可能需要考虑系统服务、ActivityManager、WindowManager等的日志。 然后,我需要考虑用户可能需要的具体信息,比如日志的类别、标签、内容以及如何查看这些日志。用户可能想知道使用ADB命令(如logcat)来捕获这些日志,或者是否有特定的过滤器可以使用。 可能需要检查Android开发者文档,了解暗色模式相关的系统事件,例如UiModeManager的配置变更。另外,应用开发者通常会在日志中输出相关信息,如主题切换时的调试信息,所以需要包括这些可能性。 还要考虑不同Android版本之间的差异,比如暗色模式在Android 10及以上是系统级支持,而在之前的版本可能由应用自行处理。因此,日志的位置和内容可能有所不同。 此外,用户可能需要示例日志条目,以便他们能够识别这些日志。例如,系统广播的ACTION_NIGHT_MODE_CHANGED,或者应用内使用AppCompatDelegate.setDefaultNightMode()时的日志输出。 最后,应该组织这些信息,分点说明系统日志和应用日志的不同来源,并给出查看这些日志的具体方法,如使用logcat命令和相应的过滤标签。</think>#### Android 手机暗色模式设置触发的日志分析 当用户在 Android 设备上启用或切换暗色模式时,系统、应用和服务可能生成多类日志。以下是主要日志类型及触发机制: --- #### 1. **系统服务日志** **触发场景**:用户通过系统设置或快捷开关切换暗色模式。 **日志来源**: - **`UiModeManager`** 系统服务 `UiModeManager` 会记录模式变更事件,例如: ```log D/UiModeManager: setNightMode(nightMode=2) D/UiModeManager: applyConfiguration() ``` - **配置变更广播** 系统发送全局广播 `ACTION_NIGHT_MODE_CHANGED`,触发日志: ```log I/ActivityManager: Broadcast: Intent { act=android.app.action.NIGHT_MODE_CHANGED } ``` **查看方法**: ```bash adb logcat -s UiModeManager ActivityManager ``` --- #### 2. **应用层日志** **触发场景**:应用响应暗色模式切换(如重启 Activity 或动态调整主题)。 **典型日志**: - **主题重载** ```log D/AppCompatDelegate: applyDayNight() D/AppCompatDelegate: setDefaultNightMode(MODE_NIGHT_YES) ``` - **资源重新加载** ```log W/ResourcesManager: Resource overlay changed, forcing update I/Choreographer: Skipped frames (UI 渲染延迟警告) ``` **查看方法**: ```bash adb logcat -s AppCompatDelegate ResourcesManager Choreographer ``` --- #### 3. **系统属性变更日志** **触发场景**:暗色模式切换可能修改系统属性 `sys.ui_night_mode`。 **日志示例**: ```log I/SystemProperties: set sys.ui_night_mode=2 D/SystemService: Notifying property change: sys.ui_night_mode=2 ``` **查看方法**: ```bash adb logcat -s SystemProperties SystemService ``` --- #### 4. **窗口管理器日志** **触发场景**:暗色模式影响界面渲染(如状态栏、导航栏颜色)。 **典型日志**: ```log D/WindowManager: updateStatusBarColor: color=0xFF1A1A1A (深色状态栏) D/SurfaceFlinger: Layer update for dark theme ``` **查看方法**: ```bash adb logcat -s WindowManager SurfaceFlinger ``` --- #### 5. **第三方应用日志** **触发场景**:应用主动监听暗色模式并记录操作(需应用自身实现日志输出)。 **示例**: ```log D/MyApp: onNightModeChanged() - Dark theme enabled D/MyApp: Recreating activity to apply new theme ``` **查看方法**: ```bash adb logcat -s MyApp ``` --- #### **如何捕获完整日志?** 1. **使用 ADB 命令** ```bash adb logcat -v time > dark_mode_logs.txt ``` 2. **过滤关键标签** 组合过滤系统与应用日志: ```bash adb logcat UiModeManager:V AppCompatDelegate:V *:S ``` (`*:S` 表示静默其他非关键日志) --- #### **注意事项** - **Android 版本差异**: - Android 10+ 使用系统级暗色模式,日志集中在 `UiModeManager`。 - Android 9 及以下依赖应用自身实现,日志可能分散。 - **厂商定制系统**: MIUI、OneUI 等可能添加私有日志标签(如 `MiuiThemeUtils`)。 - **性能影响**: 频繁切换暗色模式可能触发界面重绘,产生 `Choreographer` 跳帧警告。 --- **总结**:暗色模式切换主要触发系统服务、资源配置和界面渲染相关的日志,开发者可通过 `logcat` 按需过滤分析。用户若需调试主题问题,可重点关注 `AppCompatDelegate` 和资源配置变更日志。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值