Android避免内存泄露:合理使用getContext()和getApplication()

android学习—— context 和 getApplicationContext() 在android中常常会遇到与context有关的内容 浅论一下context : 在语句 AlertDialog.Builder builder = new AlertDialog.Builder(this); 中,要求传递的 参数就是一个context,在这里我们传入的是this,那么这个this究竟指的是什么东东呢? 这里的this指的是Activity.this,是这个语句所在的Acti 阅读详情

先作个总结:

1.getApplicationContext()可以取到Application对象,而getContext()通常认为返回Activity对象(当然,事实上并不局限于Activity)。
2.对于Application,从Manifest文件中可以看出一个应用程序一般只有一个application节点。Application其实就是一个应用,即:当前应用程序只要还处于运行状态,那么就可以取到Application对象。
3.Application是一个长引用,Activity是短引用。Application适用于存储那些需要反复读取的对象,比如用户的用户名和密码,应用程序的当前设置等。Activity适用于当前活动窗体,比如显示一个dialog,或新建一个View,传入的context对象就应该是当前Activity,而非Application。

    

 Android应用程序限制使用的堆内存是16M(注:堆内存与设备的性能也有一定关系,性能高的设备可用堆内存可能是24M或者更高),其中电话功能会占用一部分,而开发者能够使用的则非常有限。如果你不打算用完所有内存,那么你的应用就应该尽可能少用内存,从而使其他的程序在运行时不致于被杀掉。Android系统在内存中能够持有的应用程序越多,用户在程序间进行切换时就越快。作为工作的一部分,我研究Android应用中的内存泄露问题,结果发现多数情况是同一个问题引起的:对Context持有一个过长的引用。

     在Android中,Context被用在许多操作中,但多数是为了加载或访问资源。这就是为什么所有的Widget组件都会在构造器中接收一个Context参数的原因所在。对于一般的Android应用,通常有两种Context,即Activity和Application。开发者通常需要context在类或方法间传递时会选择Activity。

    这表明Views对整个Activity有一个引用,因此你的Activity中任何东西都会被(Views)持有,一般被持有的是视图层级和它对应的资源。因此,如果你泄露了Context(泄露:即你持有一个Context引用,结果阻止GC对其进行回收),你就泄露了一些内存。如果你不细心,泄露一个Activity就会变得非常容易。
    当屏幕方向改变,系统默认会保存它的状态,销毁当前Activity并重新创建一个。为了做到这一点,Android会从资源中重新加载应用程序的UI。现在假设你开发一个应用,包含了大量位图(Bitmap),你不想每次屏幕切换时都去加载位图。那么最简单的方法是利用static静态域。

    上面的代码非常简洁,但也容易出错:第一次屏幕方向改变时,最初创建的Activity(每次屏幕改变都会重新创建Activity)就会出现内存泄漏。当一个Drawable对象被附着到View中,View就会在这个Drawable上被设定作为回调callback。上面的代码片段表明drawable对TextView有一个引用,而TextView本身又对Activity(即Context)持有引用,反过来,Activity又对许多东西持有引用(这取决于你的代码)。
    上面的例子是泄露Context最简单的一种情况,你能在Home screen的源代码(查找unbindDrawables()方法)中看到我们是怎么解决它的:当Activity被销毁时,设置被存储的drawable的回调为null。有趣的是,你创建一系列内存泄露的Context会出现许多情况,并且它们都是糟糕的。它们很快使你在运行过程时出现内存溢出。
    有两种简单的方式去避免Context相关的内存泄露。最明显的一种就是避免Context超出它的范围。上面的例子展现了静态引用的情况:内部类以及对外部类的间接引用是很危险的。第二种方案是用Application。这种Context不依赖于Activity的生命周期,而是与你的应用程序同生共死。如果你打算持有一个长期活动并且需要Context引用的对象,记得使用Application对象。你可以通过调用Context.getApplicationContext() 或者 Activity.getApplication()方法得到它。
总的来说,要避免Context相关的内存泄露,铭记以下几条:

•不要对Activity(Activity继承自Context)作长期的引用(一个指向Activity的引用与Activity本身有相同的生命周期);
•(如果使用长引用)试着用Application代替Activity;

•如果你不能控制内部类的生命周期,避免使用非静态内部类,应该用静态内部类,并且对里面的Activity作弱引用。该问题的解决方法是:对于外部类,用WeakReference构造静态内部类,同时要在视图根完成,并且它的WeakReference内部类要有一个实例(WeakReference)。

•垃圾回收不是防止内存泄露的保险方式。


原文链接:Avoiding memory leaks

Fedproto:原型聚合的联邦学习框架 文中说明,联邦学习通过计算传递梯度聚合模型时,客户端之间的异构性通常会阻碍模型优化收敛和泛化性能。故本文提出新的FedProto框架,将梯度替换成为原型,通过计算、聚合从不同客户端收集到的本地原型,然后将全局原型发送回所有客户端,以规范本地模型的训练。对每个客户机进行局部训练的目的是最小化对本地数据的分类损失,同时保持生成的本地原型足够接近相应的全局原型(损失函数最小+正则)。什么是原型?文中提到:“ 阅读详情

相关推荐

Mimics 21.0软件学习笔记(一)基本操作

Materialise Mimics 21.0打开工程窗口化Thresholding 二值化Region growing区域增长创建一个3D表示,并显示股骨头从髋臼中区分出来,并单独为股骨头建立3D模型 打开工程 Opening the Project 窗口化 Windowing 二值化 Thresholding 区域增长 Region Growing 建立 3D 表示 Creating a 3D representation 显示 3D 表示 Displaying a 3D representation

qq_35495464的博客 4万+

getApplicationContext 详解

getApplicationContext 详解 1.首先我们先要知道Activity 父亲是Context ,Context 是个抽象类,ContextImpl 是Context 具体实现类.ContextWrapper也是继承于Context ,ContextWrapper使用代理方式调用ContextImpl. 2.想了解系统相关的知识,必须先要熟悉系统运行流程,系统是如何启动,如何...

博客 4万+

QCC308x/3095收发一体:TX/RX双模一拖二与多编码广播实战解析

本文深度解析高通QCC308x/3095蓝牙音频芯片的TX/RX双模功能与广播应用。芯片支持发射和接收模式下的“一拖二”连接,并能实现LE Audio多设备广播,显著提升多设备音频切换体验与商业广播能力,适用于健身、导览等丰富场景。

g9h0i1的博客 1003

Android中的getApplication()、getApplicationContext的区别与用法

getApplication() 了解getApplication()方法,首先要了解Application类,Android系统自动会为每个程序运行时创建一个Application类的对象且只创建一个,所以Application可以说是单例(singleton)模式的一个类。 Application和Activity、Service一样是Android框架的一个系统组件,当Android程序启动时系统会创建一个Application对象,用来存储系统的一些信息。 ...

weixin_42602900的博客 5129

手把手教你用STM32F103C8T6单片机,做一个即插即用的USB游戏手柄(附完整代码)

本文详细介绍了如何使用STM32F103C8T6单片机制作即插即用的USB游戏手柄,涵盖硬件搭建、HID协议解析及完整代码实现。通过深入讲解USB HID协议的七大关键描述符,帮助开发者快速掌握嵌入式USB设备开发技巧,打造个性化游戏控制器。

weixin_30887919的博客 439

Flannel,Calico 和 Cilium 之间有哪些优缺点和差别?

例如,在一个多租户的容器集群中,可以通过Calico为不同租户的容器设置精细的访问控制策略,确保每个租户的资源安全。例如,在设置复杂的网络策略和BGP路由时,需要对网络概念和Calico的配置语法有比较深入的了解。它可以根据容器的标签、服务等信息来定义访问规则,并且可以实现更加细粒度的网络安全策略,如HTTP层的策略。性能损耗:在overlay网络模式下(如VXLAN),由于需要对数据包进行额外的封装和解封装操作,会带来一定的性能损耗,尤其是在高流量的场景下,这种性能损耗可能会更加明显。

chinansa的博客 1529

Android getApplication()、getApplicationContext的区别

在 Activity 调用 getApplicationContext()返回的是当前Activity或Fragment所属的Application对象。在 Activity 调用 getApplication()通常来说,如果需要访问全局应用程序级别的变量或配置,可以使用。是两种获取应用程序上下文的方法,但它们有一些细微的区别。如果需要一个通用的应用程序级别的上下文,可以使用。四、主要的区别(Activity调用该方法)返回的是整个应用程序级别的上下文。,特别是在长时间运行的异步任务中。

帅次的博客 3080

3D高斯溅射融合Gabor滤波器:频率感知如何提升神经渲染效率与质量

在计算机视觉与图形学领域,3D场景重建旨在从多视角图像中恢复真实世界的三维结构与外观。其核心原理是通过优化场景表示,使渲染出的二维图像与输入照片尽可能一致。传统方法在效率与细节保真度间常面临权衡,高频细节(如精细纹理、锐利边缘)的重建尤为消耗算力。频率感知技术为此提供了突破方向,它借鉴信号处理思想,将场景分解为不同空间频率的成分进行针对性建模。Gabor滤波器作为经典的频率-方向分析工具,能有效刻画纹理的局部频域特征。将Gabor的频率选择性与3D高斯溅射(3DGS)这一高效显式表示结合,构成了神经Gabo

weixin_33087827的博客 272

Android Context解析以及getContext()、getApplication()、getApplicationContext()和getBaseContext()区别

Android程序不像Java程序一样,随便创建一个类,写个main()方法就能跑了,而是要有一个完整的Android工程环境,在这个环境下,我们有像Activity、Service、BroadcastReceiver等系统组件,而这些组件并不是像一个普通的Java对象new一下就能创建实例的了,而是要有它们各自的上下文环境,也就是我们这里讨论的Context。可以这样讲,Context是维持Android程序中各组件能够正常工作的一个核心功能类。

qq_38056514的博客 6131

配电变压器测控终端装置设计

配电变压器测控终端装置在电网运行中承担着数据采集、状态监测、故障预警及远程控制的关键任务,其性能直接关系到配电系统的安全性与可靠性。本研究围绕测控终端的硬件电路、软件算法、通信系统及系统优化展开深入分析,并基于实验测试验证系统性能。硬件设计包括模拟量输入电路、电压电流信号变换电路、A/D转换电路、控制与通信电路及系统电源电路,确保信号采集的高精度与系统的稳定性。软件部分涵盖系统控制程序、数据采集与处理程序、通信程序及显示与控制程序,实现数据的实时处理与传输。通信模块结合RS-485、CAN总线及以太网技术,

weixin_44553616的博客 1102

手把手教你用C语言实现GNSS卫星方位角计算(附RTKLIB风格代码解析)

本文详细介绍了如何使用C语言实现GNSS卫星方位角计算,包括从地固坐标系到站心坐标系的转换链条。通过RTKLIB风格的代码解析,展示了XYZ到ENU坐标转换的核心原理和C语言实现框架,帮助开发者掌握卫星方位角和高度角的计算技巧,适用于GNSS观测数据质量分析和精密定位算法开发。

weixin_30699915的博客 364

android内存泄露相关文章

Android开发 单例模式导致内存泄露 android开发中对context引用造成内存泄漏的一些猜测 Android避免内存泄露:合理使用getContext()和getApplication() Android应用程序级全局变量Application     未完...

victoryckl的专栏 903

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

内存泄漏注意点

http://blog.youkuaiyun.com/snow4dev/article/details/7555130   Android避免内存泄露:合理使用getContext()和getApplication() 先作个总结: 1.getApplicationContext()可以取到Application对象,而getContext()通常认为返回Activity对象(

琦琦的博客 644

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Android 中this、getContext()、getApplicationContext()、getApplication()、getBaseContext的理解和使用

依赖的activity对象。但是不推荐使用,getActivity()将返回当前Fragment的activity,当Fragment销毁时,this.getActivity()将出现空指针异常,this为null。返回应用的上下文,也就是把Application作为context。返回的是父类的context,使用getApplicationContext()都可以使用this代替。,activity继承context,所以可以使用context或activity的地方一定可以使用this。

qq_46687516的博客 2122

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

getApplicationContext(), getBaseContext(), getApplication(), getParent()区别以及context的最终解析

这四个函数的区别 原文链接http://stackoverflow.com/questions/6854265/getapplicationcontext-getbasecontext-getapplication-getparent 翻译+我的总结如下 1. getApplicationContext() : 这个函数返回的这个Application的上下文,所以是与app挂钩的,所

Shawn_Dut的专栏 1万+

Context context = getApplicationContext()

使用getApplicationContext 取得的是当前app所使用的application,这在AndroidManifest中唯一指定。意味着,在当前app的任意位置使用这个函数得到的是同一个Context 1、Context概念 其实一直想写一篇关于Context的文章,但是又怕技术不如而误人子弟,于是参考了些资料,今天准备整理下写出来,如有不足,请指出,参考资料会在醒目地方标明。 Context,相信不管是第一天开发Android,还是开发Android的各种老鸟,对于Context的使.

weixin_40721097的博客 2121

关于this、getContext()、getActivity()、getApplication()、getApplicationContext()的区别

1.MainActivity.this:表示MainActivity对象,一般用在内部类中指示外面的this,如果在内部类直接用this,指示的是内部类本身。因为MainActivity继承Activity,而Activity继承Context,所以它也可以用来提供Activity Contex; 2.this:表示当前对象;一般而言,在哪个类中调用,就是指向该对象。 3.getContext

Mr_Leixiansheng的博客 8304

getApplicationContext和Context的区别

一、什么是ContextContext的中文翻译为:语境; 上下文; 背景; 环境,在开发中我们经常说称之为“上下文”,那么这个“上下文”到底是指什么意思呢?在语文中,我们可以理解为语境,在程序中,我们可以理解为当前对象在程序中所处的一个环境,一个与系统交互的过程。getApplicationContext() 返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁。Activity.this

1694
下一篇: Android:解决“Bitmap Size Exceeds VM Budget”错误
snow4dev
博客等级 码龄15年 8粉丝 28原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值