了解 Android 应用程序中的内存泄漏

2024-03-14

我找到了这篇文章“避免内存泄漏” http://android-developers.blogspot.it/2009/01/avoiding-memory-leaks.html,其中据说有以下代码:

private static Drawable sBackground;

@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);

  TextView label = new TextView(this);
  label.setText("Leaks are bad");

  if (sBackground == null) {
    sBackground = getDrawable(R.drawable.large_bitmap);
  }
  label.setBackgroundDrawable(sBackground);

  setContentView(label);
}

这不是一个好主意,因为:

当屏幕方向改变时,系统默认情况下, 销毁当前活动并创建新活动,同时保留其 状态。这样做时,Android 将从以下位置重新加载应用程序的 UI: 资源。

所以上面的代码:

...泄漏在第一个屏幕方向更改时创建的第一个活动。当 Drawable 附加到视图时,该视图是 设置为可绘制对象的回调。在上面的代码片段中,这 意味着drawable有一个对TextView的引用,它本身有一个 对活动(上下文)的引用,而该活动又具有引用 几乎任何东西(取决于你的代码。)

但是,当屏幕方向改变时,该方法setBackgroundDrawable(可绘制背景) http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.3_r1/android/view/View.java#View.setBackgroundDrawable%28android.graphics.drawable.Drawable%29被调用,进而调用:

background.setCallback(this);

方法Drawable.setCallback()定义如下:

public final void setCallback(Callback cb) {
    mCallback = new WeakReference<Callback>(cb);
}

因此,现在后台应该释放对先前 TextView 的旧引用,并应创建对新 TextView 的新引用。

因此,似乎更改屏幕方向只会在新创建活动之前泄漏引用。

我哪里出错了?


你是绝对正确的。不过,有一个微妙的地方:该文章来自2009。当时,实施setCallback was :

安卓

public final void setCallback(Callback cb) {
    mCallback = cb;
}

安卓 >= 4.0.1:

public final void setCallback(Callback cb) {
    mCallback = new WeakReference<Callback>(cb);
}

Grepcode shows no source code of intermediate versions, this is the only diff I could quickly find.


所以,再说一遍,在这种特定情况下你是绝对正确的(如果你的目标是> 14)。然而,真正考虑当您保留对此类项目的静态引用时实际发生的情况(就像您所做的那样)仍然非常重要。在很多情况下,您肯定可能会泄露Context.

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

了解 Android 应用程序中的内存泄漏 的相关文章

  • Ubuntu 16.04 - Genymotion:找不到 /dev/hw_random

    I install Genymotion on the Ubuntu 16 04 64Bit I created a virtual emulator for Android 6 0 then I run this emulator but
  • 我想实现下面的布局,按钮应该在屏幕底部,当惰性列被填充时,按钮不应该出去

    顶部有惰性列 惰性列下方有输入电话号码布局并从电话簿布局添加联系人 我希望当未添加联系人时此布局位于顶部 当我添加大量联系人时输入电话号码并添加电话簿布局中的联系人会随着惰性列滚动并移出屏幕 我不让他们走出屏幕 当接触较多时 它们必须粘在底
  • 如何发布Android .aar源以使Android Studio自动找到它们?

    我正在将库发布到内部 Sonatype Nexus 存储库 Android Studio 有一个功能 可以自动查找通过 gradle 引用的库的正确源 我将 aar 的源代码作为单独的 jar 发布到 Nexus 但 Android Stu
  • 如何使用InputConnectionWrapper?

    我有一个EditText 现在我想获取用户对此所做的所有更改EditText并在手动将它们插入之前使用它们EditText 我不希望用户直接更改中的文本EditText 这只能由我的代码完成 例如通过使用replace or setText
  • 在 android DatePickerDialog 中将语言设置为法语

    有什么办法可以让日期显示在DatePickerDialog用法语 我已经搜索过这个但没有找到结果 这是我的代码 Calendar c Calendar getInstance picker new DatePickerDialog Paym
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • Android 套接字和 asynctask

    我即将开始制作一个应该充当 tcp 聊天客户端的应用程序 我一直在阅读和阅读 我得出的结论是最好 如果不需要 将我的套接字和异步任务中的阅读器 问题是我不确定从哪里开始 因为我是 Android 新手 这至少对我来说是一项艰巨的任务 但据我
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 一次显示两条Toast消息?

    我希望在一个位置显示一条 Toast 消息 并在另一位置同时显示另一条 Toast 消息 多个 Toast 消息似乎总是按顺序排队和显示 是否可以同时显示两条消息 是否有一种解决方法至少可以提供这种外观并且不涉及扰乱活动布局 Edit 看来
  • 将 Intent 包装在 LabeledIntent 中以用于显示目的

    要求 我的应用程序中有一个 共享 按钮 我需要通过 Facebook 分享 我需要选择是否安装原生 Facebook 应用程序 我们的决定是 如果未安装该应用程序 则将用户发送到 facebook com 进行分享 当前状态 我可以检测何时
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • 如何将 google+ 登录集成到我的 Android 应用程序中?

    大家好 实际上我需要通过我的应用程序从 google 登录人们 现在我阅读了 google 上的文档 其中指出 要允许用户登录 请将 Google Sign In 集成到您的应用中 初始化 GoogleApiClient 对象时 请求 PL
  • 如何实现仅当可用内存较低时才将数据交换到磁盘的写缓存

    我想将应用程序生成的数据缓存在内存中 但如果内存变得稀缺 我想将数据交换到磁盘 理想情况下 我希望虚拟机通知它需要内存并将我的数据写入磁盘并以这种方式释放一些内存 但我没有看到任何方法以通知我的方式将自己挂接到虚拟机中before an O
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐

  • 常量 Flask 会话 ID

    I ve a Flask应用程序 使用 Nginx WSGI FastCGI 和 Gevent 提供服务并使用标准 Flask 会话 我愿意not使用session permanent True或任何其他额外选项 但只需设置SECRET K
  • 在 Python 中打印“批准”符号/复选标记 (✓) U+2713

    如何在Python中打印复选标记 这是批准的标志 而不是平方根 您可以使用转义序列打印任何 Unicode 字符 确保创建一个 Unicode 字符串 print u u2713
  • git 中预推送和预接收钩子的区别?

    git 中的预推送和预接收钩子在用例或工作逻辑方面有区别吗 我能理解的唯一区别是他们文档 https github com git git blob master Documentation githooks txt L211就他们收到的输
  • 是否可以定义相互依赖的类型并在单独的文件中定义?

    我正在尝试实现一个具有扩展解析功能的库 我决定使用 fsyacc 因为我从大学就知道它 不幸的是我遇到了以下问题 我为我的语法头部定义了一个类 Head 并将其实现放在一个文件中 然后我将解析器定义为 start head type hea
  • 最小元素错误

    我不是 C 编码员 所以也许这很容易 我有一个 Point 类向量 我想找到 AABB 矩形 最小 x 最小 y 最小 x 最大 y 最大 x 最小 y 最大 x 最大 y 我已经完成了一个 for 循环 保存最小值和最大值 一次用于 x
  • 强制链接与库不同的 SONAME

    如何以与具有冲突 SONAME 的库的两个现有版本兼容的方式链接二进制文件 这两个版本不共享相同的 SONAME 前缀 一个是 libcapi10 so 3 另一个是 libcapi10 so 4 我无法重新编译它们 因为我将它们作为二进制
  • 在Python中反转列表切片

    我试图在 python 中反转列表的切片 但它返回一个空列表 但是当我尝试使用整个列表时 它工作得很好 我在这里错过了什么吗 l 1 2 3 4 5 6 7 8 l 1 8 7 6 5 4 3 2 1 lt lt lt This worke
  • Flink CEP:对于不同类型的事件,使用哪种方法加入数据流?

    假设我有两种不同类型的数据流 一种提供天气数据 另一种提供车辆数据 我想使用 Flink 对数据进行复杂的事件处理 Flink 1 3 x 中哪种方法是正确的使用方法 我看到了不同的方法 如 Union Connect Window Joi
  • 获取 iframe 的源代码

    有没有办法获取 iframe 加载的页面的源代码 我不想更改任何代码 我只想阅读它 我还需要能够使用 javascript html 来获取它 document getElementById iframeID contentWindow d
  • Swift 2 中“kGMSMarkerAnimationPop”错误的使用不明确

    我在尝试为 GMSMarker 制作动画时遇到错误 我已遵循 Google 文档和各种指南 但它不断返回错误 下面是我的代码 func placeMarker coordinate CLLocationCoordinate2D if loc
  • g++ 链接问题:对函数的未定义引用

    我使用 CMake 和 Visual C 构建 HyDE 库 然后 仍然在 VC 中 我能够成功创建代码并构建链接到 HyDE lib 和 HyDE 头文件的可执行文件 然后我发现 为了与我公司的其他人一起工作 最好在 Eclipse CD
  • 复选框树

    我正在寻找 Javascript 的 复选框树 小部件 我尝试使用jquery 检查树 http jquery checktree googlecode com 其声称完全符合我的要求 但它存在以下问题 它无法识别已选中的复选框 并将所有内
  • 查找用户是否是 Active Directory 组 ASP.NET VB 的成员?

    我正在使用 Active Directory 对 Intranet 站点的用户进行身份验证 我想根据用户在 Active Directory 中所在的组来优化经过身份验证的用户 有人可以向我展示或指出如何在 ASP NET 4 0 VB 中
  • 在 Angular 2 中使用 ngForTemplate 时绑定事件

    假设我有这个简单的列表渲染组件 import Input Component from angular2 core Component selector my list template div item div class MyList
  • 为什么编译器会优化掉由于 strncmp() 而导致的共享内存读取,即使使用了 volatile 关键字?

    这是一个程序foo c将数据写入共享内存 include
  • 角度结构指令上下文模板类型检查

    我似乎无法使角度模板自动完成工作 任何人都可以帮助我理解我错过了什么或做错了什么吗 div xd item div 我几乎继续研究 ngIf 和异步管道源代码 试图了解正在发生的事情 并制定了这个简单的指令 只是为了方便我的异步订阅生活 这
  • 与 Boost 和 ncurses 的静态链接

    我正在制作一个基本的角色扮演游戏 我想静态地包含 Boost 库 以便运行我的游戏的人不需要拥有它们 我研究并查找了所有你需要做的就是添加 static到命令行编译 所以我的命令是这样的 g static o karthas o lncur
  • 如何阻止不良的身份不明的机器人爬行我的网站?

    我怎样才能抵御不良的不明机器人爬行我的网站 一些名称未出现在 Apache cPanel 中的恶意机器人正在严重访问我的网站带宽 我曾在 batgap com robots txt 上尝试过 robots txt 也使用 htaccess
  • 在 boto3 1.5.36 上使用 S3.Object().put() 在 S3 中存储 matplotlib 图像

    除其他事项外 我正在使用绘图matplotlib 我想立即将其存储为 S3 对象 根据中提供的答案this https stackoverflow com q 33771318 1129682 and 这个其他 https stackove
  • 了解 Android 应用程序中的内存泄漏

    我找到了这篇文章 避免内存泄漏 http android developers blogspot it 2009 01 avoiding memory leaks html 其中据说有以下代码 private static Drawable