android ApplicationContext Context Activity 内存的一些学习
Android中context可以作很多操作,但是最主要的功能是加载和访问资源。
在android中有两种context,一种是application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。
区别联系:
public class MyActivity extends Activity {
public void method() {
mContext = this; // since Activity extends Context
mContext = getApplicationContext();
mContext = getBaseContext();
}
}
this 是Activity 的实例,扩展了Context,其生命周期是Activity 创建到销毁
getApplicationContext() 返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁
Activity.this的context 返回当前activity的上下文,属于activity ,activity 摧毁他就摧毁
getBaseContext() 返回由构造函数指定或setBaseContext()设置的上下文,SDK文档很少,不推荐使用
搞清楚了生命周期就会在使用过程中犯错误,比如有一个全局的数据操作类用到了context,这个时候就要用到getApplicationContext 而不是用ACtivity,这就保证了数据库的操作与activity无关(不会一直引用Activity的资源,防止内存泄漏)
应用场景1:
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this); //传递context给view control
label.setText("Leaks are bad");
setContentView(label);
}
把activity context传递给view,意味着view拥有一个指向activity的引用,进而引用activity占有的资源:view hierachy, resource等。
这样如果context发生内存泄露的话,就会泄露很多内存。这里泄露的意思是gc没有办法回收activity的内存。
Leaking an entire activity是很容易的一件事。当屏幕旋转的时候,系统会 销毁当前的activity,保存状态信息,再创建一个新的activity。比如我们写了一个应用程序,它需要加载一个很大的图片,我们不希望每次旋转 屏幕的时候都销毁这个图片重新加载。实现这个要求的简单想法就是定义一个静态的Drawable,这样Activity 类创建销毁它始终保存在内存中。
public class myactivity extends Activity {
private static Drawable sBackground;
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);//drawable attached to a view
setContentView(label);
}
}
这段程序看起来很简单,但是却问题很大。当屏幕旋转的时候会有leak(即gc没法销毁activity)。
我们刚才说过,屏幕旋转的时候系统会销毁当前的activity。但是当drawable和view关联后,drawable保存了view的 reference,即sBackground保存了label的引用,而label保存了activity的引用。既然drawable不能销毁,它所 引用和间接引用的都不能销毁,这样系统就没有办法销毁当前的activity,于是造成了内存泄露。gc对这种类型的内存泄露是无能为力的。
应用场景2:
pplication的Context是一个全局静态变量,SDK的说明是只有当你引用这个context的生命周期超过了当前activity的生命周期,而和整个应用的生命周期挂钩时,才去使用这个application的context。
一种推荐的用法就是应用程序注册广播broadcast时,使用这个context。
引用application context并不会导致内存泄漏。引用activity的context才会导致内存泄漏,当你的引用对象的生命周期超过了当前activity的生命 周期时,系统回收你的activity时发现还有一个context的强引用,而不去销毁这个activity,导致内存泄漏,在开发过程中,需要非常重 视这点。
避免这种内存泄露的方法是避免activity中的任何对象的生命周期长过activity,避免由于对象对activity的引用导致activity不能正常被销毁。我们可以使用application context。
application context伴随application的一生,与activity的生命周期无关。
application context可以通过Context.getApplicationContext或者Activity.getApplication方法获取。
避免context相关的内存泄露,记住以下几点:
1. 不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的
2. 对于生命周期长的对象,可以使用application context
3. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化
android ApplicationContext Context Activity 内存的一些学习的更多相关文章
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6666491 在前面一篇文章Android系统匿 ...
- 【转】Android Activity和Intent机制学习笔记----不错
原文网址:http://www.cnblogs.com/feisky/archive/2010/01/16/1649081.html Activity Android中,Activity是所有程序的根 ...
- Android Activity和Intent机制学习笔记
转自 http://www.cnblogs.com/feisky: Activity Android中,Activity是所有程序的根本,所有程序的流程都运行在Activity之中,Activity具 ...
- Android开发 |常见的内存泄漏问题及解决办法
在Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要 ...
- 老李分享:Android性能优化之内存泄漏1
老李分享:Android性能优化之内存泄漏 前言 对于内存泄漏,我想大家在开发中肯定都遇到过,只不过内存泄漏对我们来说并不是可见的,因为它是在堆中活动,而要想检测程序中是否有内存泄漏的产生,通常我 ...
- Android组件系列----Activity组件详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
- Android开发——Context类的各种细节问题
0. 前言 Context相信所有的Android开发人员基本上每天都在接触,因为它太常见了.但实际上Context有太多小的细节并不被大家所关注,那么今天我们就来学习一下那些你所不知道的细节. ...
- Android中常见的内存泄漏
为什么会产生内存泄漏? 当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏. ...
- Android中Context解析
Context概念 当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context. Context是一个抽象基类,我们通过它访问当前包的资源(getResources.getA ...
随机推荐
- php 积少成多!
- UNIX基础--控制台和终端
虚拟控制台和终端 Virtual Consoles and Terminals: FreeBSD 虚拟控制台的默认配置为8个,但并不是硬性设置, 您可以很容易设置虚拟控制台的个数增多或减少. 虚拟控制 ...
- Openjudge-计算概论(A)-称体重
描述: 赵.钱.孙.李四个人中既有大人也有小孩,给他们称体重时发现,他们每个人的体重都不一样,且体重(单位:公斤)恰好是10的整数倍,且他们的体重都不高 于50公斤,已知赵.钱两人的体重之和恰好等于孙 ...
- Android:assests和raw的区别
转自:http://www.cnblogs.com/lianghui66/p/3248636.html ------------------------------------------------ ...
- apache 不执行PHP,显示代码
首先检查是否安装PHP,已经安装过的话,先执行 locate libphp5.so 查看APACHE是否有SO文件,如果没有,那就要重装PHP了,先执行php -i | grep configure ...
- 第三十五节,json数据类型转换字符串模块
在使用json模块时需要先 import json 引入模块 json.dumps()模块函数 功能:将Python数据类型转换成字符串[有参] 使用方法:json.dumps(要转换的数据类型变量) ...
- python unitest基本
基本 import unittest class OneTest(unittest.TestCase): def setUp(self): self.verificationErrors = [] s ...
- HDU 1548 A strange lift(dij+邻接矩阵)
( ̄▽ ̄)" //dijkstra算法, //只是有效边(即能从i楼到j楼)的边权都为1(代表次数1): //关于能否到达目标楼层b,只需判断最终lowtime[b]是否等于INF即可. # ...
- angular中的ng-bind-html指令和$sce服务
angular js的强大之处之一就是他的数据双向绑定这一牛B功能,我们会常常用到的两个东西就是ng-bind和针对form的ng-model.但在我们的项目当中会遇到这样的情况,后台返回的数据中带有 ...
- 兼容IE低版本
1,IE6PNG透明的bug,只需要把png图另存为无杂边的png-8格式 2,在IE6用overflow:hidden清除浮动,要加上zoom:1 3,IE6下盒子的最小高度为20px 如果要小于2 ...