`

Android application context/activity context与内存泄露

阅读更多
在android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。
比如一个activity的onCreate:
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,保存状态信息,再创建一个新的。

比如我们写了一个应用程序,它需要加载一个很大的图片,我们不希望每次旋转屏幕的时候都销毁这个图片,重新加载。实现这个要求的简单想法就是定义一个静态的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对这种类型的内存泄露是无能为力的。

避免这种内存泄露的方法是避免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. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化
1
0
分享到:
评论

相关推荐

    谈谈Android里的Context的使用

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > android:...

    android activity跳转 Application Context实现共享数据

    涉及:activity跳转、intent使用、startActivityForResult/onActivityResult,着重讲解通过来Application Context实现共享数据

    android检查内存泄露

    android检查内存泄露和用法 <!--==============================================================================--> android:name="com.squareup.leakcanary.internal.HeapAnalyzerService" android:enabled...

    避免 Android中Context引起的内存泄露

    Context是我们在编写Android...本文讲介绍Android中Context,更具体的说是Activity内存泄露的情况,以及如何避免Activity内存泄露,加速应用性能。 Drawable引起的内存泄露 Drawable引起内存泄露这个问题是比较隐晦,

    Android编程中context及全局变量实例详解

    本文实例讲述了Android编程中...第一种中context的生命周期与Application的生命周期相关的,context随着Application的销毁而销毁,伴随application的一生,与activity的生命周期无关。第二种中的context跟Activit

    Introduction.to.Android.Application.Development(4th,2013.12) pdf

    Adding Logging Support to Your Android Application 83 Adding Some Media Support to Your Application 84 Adding Location-Based Services to Your Application 88 Debugging Your Application on Hardware 90 ...

    ContentProvider

    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.tigongzhe" android:versionCode="1" android:versionName="1.0" > android:minSdkVersion="8" android:...

    android中用getApplicationContext()会不会避免某些内存泄漏问题?

    作者:Hewi ...来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。...首先,Activity的Context和Application的Context肯定不是一个东西,一个是当前活动的 Context,它的生命周期仅限

    android基础教程之context使用详解

    在android中有两种context,一种是application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。 区别联系: 代码如下:public class MyActivity extends Activity { public ...

    Android编程实现全局获取Context及使用Intent传递对象的方法详解

    本文实例讲述了Android编程实现全局获取Context及使用Intent传递对象的方法。分享给大家供大家参考,具体如下: 一、全局获取 Context Android 开发中很多地方需要用到 Context,比如弹出 Toast、启动活动、发送广播...

    Android代码-AndroidHookStartActivity

    1.application标签里配置一个壳Activity 2.注册一下其中this为context AMSHookUtil.hookStartActivity(this); 3.以后就可以按照标准的Intent启动为那些未被注册的Activity。 Intent intent = new Intent...

    Android代码-Android_Learning_Notes

    3、Android03--Context和Application 4、Android04--Android服务 5、Android05--Android服务通信 6、Android06--Android广播接收器 7、Android07--Android日志系统 8、Android08--Android权限系统 用户界面 9、...

    Android代码-support-application

    support-application is a library which can get the information about the app like application, applicationContext, classloader, appName, versionName, versionCode, isDebugAble without context. ...

    Android开发之activity的生命周期详解

    本文实例讲述了Android activity的生命周期。分享给大家供大家参考,具体如下: activity类处于android.app包中,继承体系如下: 1.Java.lang.Object 2.android.content.Context 3.android.app.ApplicationContext 4...

    Android功能代码

    Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_SETTINGS);//管理应用程序界面 context.startActivity(intent); 或者用以下方法(3.0以前的版本可以用此方法) Intent intent = new Intent...

    打开附件.java

    import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Environment; import android.widget.Toast; import java.io.File; /** * Created by niuyouquan ...

    Android移动开发实验4.doc

    " "(8)完成以上操作后,在"包资源管理器"中的项目名称节点上,单击鼠标 " "右键,在弹出的快捷菜单中,选择"运行方式/Android " "Application"菜单项通过模拟器运行程序。 " "四、程序调试(结果及分析) " " " ...

    新版Android开发教程.rar

    https://sites.google.com/a/android.com/opensource/release-features Android Android Android Android 盈利模式 Android 的 App Market 模式,软件开发者获得 7 成收入, 3 成用于系统维护。难点在于位置营销。 ...

    Android项目设计与开发:服务的概念.ppt

    嵌入式Android项目设计与开发 第八章 服务 —— 服务的概念 服务的概念 服务(Service)是Android中的四大组件之一,它能够长期在后台运行且不提供用户界面。即使用户切到另一应用程序,服务仍可以在后台运行。 服务...

Global site tag (gtag.js) - Google Analytics