Android 如何将一个app 设置为持久app, 不被low memory kill 关闭

本文详细介绍了如何通过修改Android应用的manifest文件、使用平台签名和放置在system/app目录下,来将一个应用设置为持久运行状态,从而减少被低内存杀手(lowmemorykiller)关闭的风险。请在实施前谨慎考虑其潜在影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言
         欢迎大家我分享和推荐好用的代码段~~
声明
         欢迎转载,但请保留文章原始出处:
         优快云:http://www.youkuaiyun.com
         雨季o莫忧离:http://blog.youkuaiyun.com/luckkof

正文

 

[Description]
如何将一个app 设置为常住app, 不被low memory kill 关闭

[Keyword]

app 持久 persistent

[Solution]

1. 将app 的manifest.xml 中的 application 中添加属性 android:persistent="true"

2. 对这个APP 使用platform 的签名

3. 放置在system/app 下面

注: 一个app 被设置为 persistent 后,将很难被low memory kill 杀掉(oom_adj=-12),请在设置之前仔细确认是否必须,否则将浪费掉memory。

<think>我们讨论的是Android中Activity被finish的原因及判断方法。用户问题集中在如何判断Activity被finish的具体原因。根据引用[5],Activity中有一个isFinishing()方法可以用来判断Activity是否正在被finish。在finish()调用后,Activity会经历onPause()、onStop()、onDestroy()等生命周期回调。在onPause()方法中就可以通过isFinishing()方法判断是否正在被finish(此时返回true)。但是,用户的问题是如何判断Activity被finish的“原因”,而仅仅是判断是否被finish。这需要更深入的分析。实际上,Activity被finish的原因可能有多种:1.用户主动按下返回键(Back键)导致finish。2.程序中调用了finish()方法(可能是按钮点击事件、网络请求回调等)。3.系统由于资源限制而关闭Activity(比如在后台时被系统杀死)。4.配置变更(如旋转屏幕)导致Activity被销毁并重新创建(这种情况下,原来的Activity会被finish,然后创建一个新的)。然而,Android系统并没有直接提供获取finish原因的方法。因此,我们需要根据同的场景和生命周期回调中的一些信息来推断。以下是一些判断思路:1.通过生命周期回调的顺序判断:-正常情况下,当用户按返回键或主动调用finish()时,生命周期回调顺序为:onPause()->onStop()->onDestroy()。-如果是因为配置变更而finish,则在onDestroy()之前会调用onSaveInstanceState()保存状态,然后系统会立即重新创建Activity。2.在onDestroy()方法中检查isFinishing()方法:-如果isFinishing()返回true,表示是程序主动调用了finish()(或者用户按Back键)导致的finish。-如果isFinishing()返回false,则可能是系统为了释放资源而销毁Activity(比如内存足),或者是配置变更导致的销毁(此时虽然调用了onDestroy,但isFinishing()为false)[^3]。3.通过重写onBackPressed()方法判断返回键:-当用户按下返回键时,系统会调用onBackPressed(),然后默认会执行finish()。因此可以在onBackPressed()中设置标志位,然后在onDestroy()中检查这个标志位来判断是否因返回键退出。4.使用ActivityLifecycleCallbacks监听所有Activity的生命周期,但这种方法难以获取具体原因。5.针对配置变更,可以在onConfigurationChanged()中处理(即让系统重新创建Activity),然后在重新创建的Activity中通过getIntent()或者之前保存的状态来判断上一个Activity是否是因为配置变更而被销毁。6.对于系统资源足导致的销毁,我们可以通过onSaveInstanceState()方法被调用(并且是配置变更引起)来推断。因为系统在可能被销毁之前会调用onSaveInstanceState()保存状态,以便重建时恢复。示例代码:判断返回键导致的finish:```javaprivatebooleanisFinishedByBack=false;@OverridepublicvoidonBackPressed(){isFinishedByBack=true;super.onBackPressed();}@OverrideprotectedvoidonDestroy(){super.onDestroy();if(isFinishing()){if(isFinishedByBack){//用户按返回键导致的finish}else{//程序中调用finish()导致的}}else{//非主动finish,可能是配置变更或系统销毁}}```注意:配置变更导致销毁时,isFinishing()返回false,因此我们可以通过onDestroy中的isFinishing()和之前设置的一些标志位(如是否配置变更)来区分。但是,我们无法在onDestroy中区分是配置变更还是系统资源足导致的销毁(因为在这两种情况下,isFinishing()都返回false)。通常,我们可以通过onSaveInstanceState()是否被调用来辅助判断:如果是系统资源足导致的销毁,会先调用onSaveInstanceState(),然后调用onDestroy(),并且没有配置变更(即会立即重建)。而配置变更导致的销毁,在销毁后立即重建。另外,我们还可以在onDestroy()中通过getChangingConfigurations()来查看是否是配置变更(但这个方法在销毁时可能准确,一般这样用)。更常见的做法是在onDestroy中检查isChangingConfigurations()方法(APIlevel11以上):```java@OverrideprotectedvoidonDestroy(){super.onDestroy();if(isFinishing()){//主动finish}else{if(isChangingConfigurations()){//因配置变更而销毁}else{//系统资源足等原因销毁}}}```然而,根据官方文档,isChangingConfigurations()在以下情况下返回true:-该Activity正在被销毁,因为系统希望重新创建它(由于配置变更)。-该Activity正在被销毁,因为其所属的Task被清空(比如Task被用户清除,此时是配置变更)。因此,使用isChangingConfigurations()能完全准确判断配置变更。更可靠的方式是,配置变更导致的销毁通常伴随着新Activity的立即重建,因此我们可以通过一个静态变量(或ViewModel)来记录配置变更的标志,然后在onDestroy中根据这个标志来判断。但是静态变量在进程杀死时无效。综上所述,我们可以结合多种方法来综合判断finish的原因:1.是否为返回键:通过重写onBackPressed设置标志。2.是否为程序调用finish:在调用finish的地方设置标志(例如在按钮点击事件中设置标志)。3.是否为配置变更:在onDestroy中使用isChangingConfigurations(),同时观察onSaveInstanceState的调用情况。4.系统资源销毁:在onDestroy中,如果isFinishing()为false且isChangingConfigurations()为false,则可能是系统资源销毁。但要注意,这些判断在onDestroy中可能已经为时过晚,有些资源已经释放。另外,引用[3]中提到:当没有任何消息待处理时(主线程空闲时),系统会处理那些被finish的activity的stop或finish操作。因此,在finish()调用后,Activity会立即被销毁,而是等到主线程空闲时才会执行生命周期回调。综上所述,我们无法100%精确地判断Activity被finish的原因,但通过标志位和系统提供的方法可以推断出常见的原因。下面,我们根据用户的问题,给出一个回答。</think> ### Android Activity 被 Finish 的原因分析与判断方法 在 Android 系统中,Activity 被 `finish()` 调用的原因可分为 **主动触发** 和 **系统行为** 两类。以下是具体判断方法和对应场景的详细分析: --- #### 一、主动 Finish 的场景判断 当以下条件满足时,Activity 被显式调用 `finish()`: ##### 1. **代码中直接调用 `finish()` 方法** ```java // 在按钮点击事件中调用 finish() button.setOnClickListener(v -> { finish(); // 标记为主动销毁 [^4] }); ``` - **判断方法**:全局搜索代码中的 `finish()` 调用位置 - **特点**:通常发生在用户交互(点击按钮)、任务完成或流程跳转后 ##### 2. **通过 `startActivityForResult` 返回结果** ```java // 子 Activity 返回结果并 finish setResult(RESULT_OK); finish(); // 显式终止自身 [^1] ``` - **判断方法**:检查 `onActivityResult()` 回调逻辑 - **调试技巧**:通过日志追踪 `setResult()` 与 `finish()` 的调用顺序 --- #### 二、系统自动 Finish 的行为判断 当 Activity 未被显式调用 `finish()` 却销毁时,需关注系统行为: ##### 1. **资源限制导致回收** - **触发条件**: - 系统内存足(后台进程被清理) - 长时间无响应的 ANR(Application Not Responding) - **判断方法**: ```java override fun onDestroy() { if (!isFinishing) { // isFinishing = false 表明非主动销毁 [^5] Log.d("Recovery", "系统强制回收") } } ``` - **关键特征**:日志中输出 `kill` 相关提示(如 `Reason: low memory`) ##### 2. **配置变更(ConfigChange)重建** ```java // Manifest 未声明处理旋转等操作 <activity android:name=".MainActivity" android:configChanges="orientation|screenSize"> // 声明可避免销毁 ``` - **现象**:旋转屏幕导致重建新 Activity,旧实例调用 `onDestroy()` - **判断标志**:`isChangingConfigurations() == true` [^3] ##### 3. **任务栈(Task)清理** ```java // 启动时清空栈内其他 Activity intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); ``` - **结果**:位于目标 Activity 上方的所有实例均被 finish - **定位方式**:检查 Intent 启动标志(`FLAG_ACTIVITY_*`) --- #### 三、调试技巧与验证方法 ##### 1. **生命周期监控** 添加生命周期日志验证调用顺序: ```java override fun onDestroy() { Log.d("LIFECYCLE", "onDestroy: isFinishing=${isFinishing}") super.onDestroy() } ``` 输出逻辑: - **主动 finish**:`onPause→onStop→onDestroy`,且 `isFinishing=true` [^5] - **系统回收**:`onStop→onDestroy`(可能跳过 `onPause`),且 `isFinishing=false` ##### 2. **检查异常日志** 过滤以下关键日志: ```bash adb logcat | grep -E "ActivityManager|Finished" # 输出示例: # ActivityManager: Force stopping com.example.app # ActivityManager: Finish task: TaskId=123 ``` ##### 3. **覆盖关键回调方法** ```java override fun finish() { Log.w("DEBUG", "手动触发销毁!调用栈:", Throwable()) super.finish() } ``` 通过异常堆栈定位调用源头。 --- ### 相关问题 1. 如何区分配置变更导致的销毁与内存足销毁? 2. `onSaveInstanceState()` 在何种销毁场景下会被调用? 3. Android 14 的 `PendingIntent` 限制对 Activity 销毁有何影响? 4. 如何在多模块工程中全局监控 Activity 销毁事件? 5. `ViewModel` 能否在系统强制回收后恢复数据? [引用说明] [^1]: Activity 通过 `setResult()` 和 `finish()` 返回结果的操作逻辑 [^3]: 系统空闲时处理 Activity 销毁的机制说明 [^4]: `finish()` 在 UI 事件中的调用示例 [^5]: `isFinishing()` 标志位的判断逻辑与生命周期关联
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值