在onPause而不是onDestroy中释放资源

2024-03-31

这是关于后蜂窝状(即Android 3.0+)以及下面的引用来自https://developer.android.com/reference/android/app/Activity.html https://developer.android.com/reference/android/app/Activity.html

根据生命周期,onStop 和 onDestroy 是可杀死的,这意味着:

请注意上表中的“Killable”列——对于这些方法 被标记为可杀死的,在该方法返回之后 托管该活动的进程可能随时被系统终止 没有执行另一行代码

  1. 换句话说,onStop(以及在此事件之前发生的其他事件)是保证被调用,但在方法返回的那一刻,进程可能会死亡,因此 onDestroy 是不保证被称为。

    另一段引述指出:

    对于那些没有标记为可杀死的方法, Activity的进程不会被系统杀死 调用该方法并在返回后继续执行的时间。

    其次是

    因此,一项活动是在killable状态,例如,之后之间 onPause() 到 onResume() 的开始。

  2. 但这确实not对应上面所说的,unless这仅对应于预蜂窝状。这不适用于后蜂窝状, 正确的?所以基本上,onPause 和 onStop 都保证被调用。

  3. 假设我只在 onDestroy 中释放资源,那么这可能会导致可能的泄漏,因为 onDestroy 可能不会被调用,对吧?

  4. 但是,这种情况(即onDestroy没有被调用)会发生吗?besides当进程被android本身杀死时?是否还有其他场景导致 onDestroy 不被调用,从而泄漏资源.

  5. Android杀死进程时资源是否会被销毁并且不会发生泄漏(即使我们没有明确释放资源?)。

请提供详细信息,说明这些陈述 (1) (2) (3) (4) (5) 是否正确。


首先让我们了解一下您引用的文档是怎么回事。

以下命令显示git blame的输出Activity.javaAOSP 中的文件:

$ cd $AOSP/frameworks/base
$ git blame ./core/java/android/app/Activity.java

输出的相关部分:

9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  363)  * <p>Note the "Killable" column in the above table -- for those methods that
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  364)  * are marked as being killable, after that method returns the process hosting the
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  365)  * activity may killed by the system <em>at any time</em> without another line
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  366)  * of its code being executed.  Because of this, you should use the
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  367)  * {@link #onPause} method to write any persistent data (such as user edits)
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  368)  * to storage.  In addition, the method
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  369)  * {@link #onSaveInstanceState(Bundle)} is called before placing the activity
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  370)  * in such a background state, allowing you to save away any dynamic instance
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  371)  * state in your activity into the given Bundle, to be later received in
550116576 (RoboErik                        2014-07-09 15:05:53 -0700  372)  * {@link #onCreate} if the activity needs to be re-created.
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  373)  * See the <a href="#ProcessLifecycle">Process Lifecycle</a>
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  374)  * section for more information on how the lifecycle of a process is tied
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  375)  * to the activities it is hosting.  Note that it is important to save
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  376)  * persistent data in {@link #onPause} instead of {@link #onSaveInstanceState}
5c40f3fcc (Daisuke Miyakawa                2011-02-15 13:24:36 -0800  377)  * because the latter is not part of the lifecycle callbacks, so will not
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  378)  * be called in every situation as described in its documentation.</p>
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  379)  *
0aae2d4e0 (Dianne Hackborn                 2010-12-07 23:51:29 -0800  380)  * <p class="note">Be aware that these semantics will change slightly between
0aae2d4e0 (Dianne Hackborn                 2010-12-07 23:51:29 -0800  381)  * applications targeting platforms starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB}
0aae2d4e0 (Dianne Hackborn                 2010-12-07 23:51:29 -0800  382)  * vs. those targeting prior platforms.  Starting with Honeycomb, an application
0aae2d4e0 (Dianne Hackborn                 2010-12-07 23:51:29 -0800  383)  * is not in the killable state until its {@link #onStop} has returned.  This
0aae2d4e0 (Dianne Hackborn                 2010-12-07 23:51:29 -0800  384)  * impacts when {@link #onSaveInstanceState(Bundle)} may be called (it may be
0aae2d4e0 (Dianne Hackborn                 2010-12-07 23:51:29 -0800  385)  * safely called after {@link #onPause()} and allows and application to safely
0aae2d4e0 (Dianne Hackborn                 2010-12-07 23:51:29 -0800  386)  * wait until {@link #onStop()} to save persistent state.</p>
0aae2d4e0 (Dianne Hackborn                 2010-12-07 23:51:29 -0800  387)  *
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  388)  * <p>For those methods that are not marked as being killable, the activity's
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  389)  * process will not be killed by the system starting from the time the method
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  390)  * is called and continuing after it returns.  Thus an activity is in the killable
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  391)  * state, for example, between after <code>onPause()</code> to the start of
9066cfe98 (The Android Open Source Project 2009-03-03 19:31:44 -0800  392)  * <code>onResume()</code>.</p>

请注意,讨论蜂巢后行为的段落是由 Dianne Hackborn 在 2010 年 12 月 7 日添加的,而所附段落可追溯到 2009 年 3 月 3 日。

它告诉我们的是 Dianne 添加了新段落而没有更新 javadoc 的其余部分,因此存在矛盾。不幸的是,这种情况在 Android 中并不罕见。

对于您的问题:

1) 在后 Honeycomb 版本的 Android 上onResume() and onStop()保证被调用(正如 Dianne Hackborn 在 Activity 的 javadoc 中补充的那样)。

2) 仅适用于蜂巢之前onPause()保证被调用(如早期版本的 Activity 的 javadoc 中所述)

3,4,5) onDestroy()仅当托管整个应用程序的进程被终止时才不会被调用。当进程被终止时,分配给它的所有资源都将被释放,因此在这种情况下不存在内存泄漏的风险。

重要的提示:自从释放资源以来onDestroy()不会导致内存泄漏,将所有“释放”代码放在那里可能看起来是个好主意。然而,它很少是最佳方法。为什么?参见下文。

When Activity进入后台,它被停止,但不会被破坏(通常)。Activity可以在相当长的时间内保持这种“停止”状态,并且如果用户返回到应用程序,则将再次启动。如果您释放资源onDestroy(),默认情况下不会调用Activity进入后台,Activity将在停止状态下保留这些资源,从而导致您的应用程序在后台状态下消耗更多的资源。

当 Android 内存不足时,它会开始终止进程​​以释放它们消耗的内存。选择要终止的进程时要考虑的最重要的考虑因素之一是它们的资源消耗。因此,如果您的应用程序在后台停止状态下保留资源,那么它将有更高的机会被 Android 杀死。

此外,我们开发人员必须确保为用户制作最好的应用程序。在后台消耗大量用户手机资源和电池的应用程序不是一个好的应用程序。用户会知道这一点!

因此,我强烈建议释放所有资源onStop()方法。我通常不会覆盖onDestroy()中的方法Activities and Fragments at all.

推论:正如 @Juan 在他的评论中指出的,上述重要注释有一个同样重要但不那么明显的推论:onStart()应该是分配资源的唯一方法。无论你对“资源”的定义是什么,两者都不是onCreate() nor onResume()应该分配这些资源。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在onPause而不是onDestroy中释放资源 的相关文章

  • 是否可以使用最新的 APP_PLATFORM,同时仍保持向后兼容性?

    这是我的 Application mk APP ABI armeabi v7a APP PLATFORM android 16 APP OPTIM release APP STL gnustl static APP CPPFLAGS std
  • Android 上的 Firebase:如何检查 Firebase 身份验证失败原因?

    我在 Android 上使用 Firebase 和 Firebase Auth 功能 I try FirebaseAuth signInWithEmailAndPassword如果失败 我想知道为什么登录过程失败 The signInWit
  • 如何在 Android 上创建 YouTube 的双击手势?

    我在 Android 上有 exoplayer 的应用程序 我已经创建了 youtube双击手势用动画向前或向后跳跃 10 秒 如何在双击时创建具有波纹效果的半圆 像这样 这个怎么做 我也想实现这样的功能 所以我自己编写了它来 复制 You
  • 使用 Android 播放任意音调

    有没有办法让Android发出任意频率的声音 意思是 我不想预先录制声音文件 我环顾四周 音调发生器 http developer android com reference android media ToneGenerator html
  • 获取可以共享数据的应用程序列表

    此代码显示默认共享对话框 Intent sharingIntent new Intent Intent ACTION SEND sharingIntent setType text html sharingIntent putExtra a
  • 从多个选项卡中的编辑文本字段获取文本

    我正在尝试创建一个使用选项卡作为输入表单的 Android 应用程序 基本上 我希望对其进行设置 以便用户可以在一个选项卡上输入一些信息 然后提交该信息 或者转到另一个选项卡并输入更多信息 然后从两个选项卡提交信息 我正在使用操作栏和片段来
  • Android Web Intent 问题

    G day 免责声明 我不是 Android 开发人员 我正在对我所描述的问题进行质量检查 我用来描述这个问题的技术术语可能是错误的 我正在测试一个 Android 应用程序 该应用程序在其清单中描述它可以使用 type 的地址处理 Web
  • Google 移动广告和 Kindle Fire

    我最近用 Google 移动广告替换了 AdMob 库 对此我有一个疑问 广告会出现在 Amazon Kindle Fire 设备上吗 我问这个是因为我知道 Google 移动广告依赖于 Google Play 服务 所以我有点困惑 Goo
  • 加快 ImageView 中的缩放功能

    我目前正在处理非常大的图像 7 10mb 由于多种原因无法调整大小或压缩 现在 我们的想法是在自定义 ImageView 中显示它们 使用户能够进行双击缩放 捏合缩放等 我使用这个库来完成这项工作 https github com Mike
  • 在 AppAuth-Android 中注销

    我有一个用JAVA开发的Android应用程序 对于这个应用程序 我使用的是身份服务器4 https github com IdentityServer IdentityServer4作为我的 STS 一切正常 但我找不到任何注销的实现Ap
  • 如何在Android Compose中使用otf类型字体文件?

    我正在学习使用 Android Jetpack Compose 现在我有一个正则 otf字体文件在资产 字体 我想在文本中使用它 java lang RuntimeException Font asset not found commonu
  • android 中camera.setParameters 失败

    我已将相机功能包含在我的应用程序中 我还在市场上推出了该应用程序 我从一位用户那里收到一条错误消息 称他在打开相机时遇到错误 我已经在 2 1 的设备上测试了该应用程序 我从用户那里得到的错误是使用 Nexus One 它主要运行 2 2
  • 使用嵌套的 hashmap 参数发送 volley 请求

    我正在使用 android volley 框架向我的服务器发送 jsonobject 请求 get 请求工作正常 现在我想发送一个带有请求参数的 post 请求 该请求参数是嵌套的 hashmap 我重写 getparams 方法 但它期望
  • Android:打开和关闭SQLite数据库

    我正在开发Android应用程序 我经常在其中访问本地数据库 该数据库可以从不同的主题访问 因此我遇到了数据库的协调问题 我使用以下open and close method public void open mDb mDbHelper g
  • 检测 ListView(或 ScrollView)内的滚动位置

    我正在构建一个聊天室应用程序 其中每 X 秒就会轮询一次新事件 每次发生这种情况时 此代码都会使用新数据更新 RoomAdapter ArrayAdapter 的自定义子类 并将其滚动到底部 RoomAdapter adapter Room
  • Android:确定 2.2 及更高版本上的摄像头数量

    我的应用程序需要在 Android 2 2 及更高版本上运行 我需要一种方法来确定可用摄像机的数量 有很多帖子解决了这个问题 但我找不到一个有效的 一种解决方案是简单地检测操作系统版本 任何 2 2 版本的设备都仅限于 1 个摄像头 即使该
  • Android - iphone 风格 tabhost [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • android:layout_alignParentBottom 在没有显式布局高度作为 ListView 中的行的情况下使用时会被忽略

    当我使用RelativeLayout与任一fill parent or wrap content作为高度和一个指定的元素 android layout alignParentBottom true 它被忽略并在顶部对齐 设置高度Relati
  • 如何在Android中解析xml类型的HTTPResponse

    我有一个 Android 应用程序 我使用 POST 方法来获取响应 这是我的代码 HttpResponse httpResponse httpclient execute httppost HttpEntity resEntity htt
  • 如何以编程方式创建活动转换?

    我想以编程方式创建一个动画 以从触摸屏点启动具有缩放效果的活动 接下来我模拟缩放输入效果

随机推荐

  • gccfilter 和 gcc 4.7.2 不起作用,停止编译

    我已经成功安装了海湾合作委员会过滤器 http www mixtion org gccfilter http www mixtion org gccfilter 在我的工具链中 过滤器实际上应该工作 因为所有 perl 模块和其他东西都已安
  • 如何通过 liquibase 更改自动增量列的起始值?

    我的数据库使用 MySql 我已经找到了如何在创建表时设置列的起始自动增量值 但我需要知道如何为现有列设置新的起始值 执行此操作的 liquibase 脚本是什么样的 MySQL 语法非常简单 ALTER TABLE mytable AUT
  • 我想将我的 firebase 信息与我的邮件连接起来

    我刚刚创建了一个联系表单 并使用 firebase 实时数据库来获取想要联系我的网站访问者的信息 现在 每次访问者从网站发送联系人提交时 我希望收到一封包含 firebase 信息表单的电子邮件 如何将 firebase 实时数据库与我的电
  • 如何在给定的时间间隔运行 Unix 命令?

    我想运行 Unix 命令 例如ls 通过脚本每隔 5 分钟一次 解释 我有一个 Unix 脚本 在该脚本中我有一个名为 ls 的命令 我希望该脚本中的 ls 命令每 5 分钟运行一次 Use watch The nflag 指定以秒为单位的
  • ObservableCollection 的替代品?

    我正在寻找替代品ObservableCollection这是线程安全的 在 UI 线程上引发事件 并且最好有一个AddRange方法 我已经在此处和其他地方看到了一些实现 但我更喜欢已经过测试和验证的实现 并且我不必自己维护 那么有人可以向
  • 使用符号批量输入时的张量流 LSTM 模型样本

    我正在为句子构建下一个字符预测 LSTM 我正在关注这里的教程https indico io blog tensorflow data inputs part1 placeholders protobufs queues https ind
  • 使用SBT构建纯Java项目

    过去我曾使用 Ant Ivy 或 Maven 来构建我的 Java 项目 我现在正在寻找非基于 xml 的解决方案 Gradle 可以编译 jar 和发布我的项目 几乎没有问题 我可以用 SBT 做同样的事情吗 如果是这样 您能否提供一个使
  • SQL 排名百分位

    我做了一个 SQL 查询 根据页面被查看的次数对页面进行排名 例如 PAGE VIEWS J 100 Q 77 3 55 A 23 2 6 现在我想做的是使用 SQL 查询找到每个页面的百分位数排名 我想使用的数学非常简单 我只想将已生成的
  • 下载大型视频文件被损坏

    在服务器端代码中 我将缓冲区大小和内容长度设置为文件长度 然后使用打开文件文件输入流 稍后使用获取输出流HttpResponse getOutputStream 并转储使用读取的数据字节文件输入流 我正在使用 Apache Tomcat 7
  • 使用希伯来数字自定义
      编号

    我想要一个使用希伯来字母数字的编号列表 就像希伯来语书籍中常见的那样 拉丁语表示法使用数字 0 9 而希伯来语则按字母顺序编号 但有时值会发生变化 我不知道这在 CSS 中是否可行 但也许在 JavaScript 中可行 我基本上想要这样的
  • Selenium webdriver 无法点击页面外的链接

    我在使用 Selenium WebDriver 时遇到问题 我尝试单击窗口页面外部的链接 您需要向上滚动才能看到它 我当前的代码相当标准 menuItem driver findElement By id MTP menuItem clic
  • 无法更改 iTunes Connect 中的主要语言

    我已向 App Store 提交了我的第一个应用程序 不幸的是 我注意到主要语言设置为德语而不是英语 我尝试更改主要语言 但出现错误 为了将此应用程序的主要语言更改为英语 美国 每个版本必须已经具有所需的英语 美国 屏幕截图 但我已经上传了
  • 如何在另一个应用程序中使用一个 gwt 应用程序的源代码

    我有两个不同的 gwt 项目 并且想要在另一个模块中使用一个 gwt 应用程序的类 有什么办法可以做到这一点吗 我遵循以下方法 在第二个项目中添加了以下两行
  • 我应该使用公共变量还是私有变量?

    我第一次做一个大型项目 我有很多类 其中一些具有公共变量 一些具有带有 setter 和 getter 方法的私有变量 并且相同具有两种类型 我决定重写此代码以主要仅使用一种类型 但我不知道应该使用哪个 仅用于同一对象中的方法的变量始终是私
  • Visual Studio 2005/2012:如何将第一个花括号保持在同一行?

    尝试让我的 css C 函数看起来像这样 body color 222 而不是这个 body color 222 当我自动格式化代码时 C In the Tools菜单点击Options Click 显示所有参数 左下角的复选框 显示所有设
  • 使用 C# 按创建日期降序获取目录中的文件列表

    我想使用 C 获取按创建日期排序的文件夹中的文件列表 我正在使用以下代码 if Directory Exists folderpath DirectoryInfo dir new DirectoryInfo folderpath FileI
  • URL 问号后面的部分是什么术语?

    http www example com foo 该术语是什么foo网址的一部分 这是query 或者有时请求参数 从中捏取有用的图表URI RFC https datatracker ietf org doc html rfc3986 s
  • lua检查多个值是否相等

    我喜欢用 Roblox 制作游戏 并用 lua 编写代码 在编写游戏时 我发现自己经常问一个值是否等于另一个值 这可能会产生很长的代码行 并且可能非常重复 例如 如果 x ClassName 衬衫 或x ClassName 附件 或x Cl
  • (转)发送http请求时如何控制gzip压缩?

    我想问一下大家在请求HTTP Post消息时如何控制gzip压缩 Accept Encoding gzip 作为 Http 请求标头始终添加到我发送的 http 请求中 但我不想使用 gzip 压缩 我该如何处理 在执行http NewRe
  • 在onPause而不是onDestroy中释放资源

    这是关于后蜂窝状 即Android 3 0 以及下面的引用来自https developer android com reference android app Activity html https developer android c