`

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 activity跳转 Application Context实现共享数据

    在Android应用开发中,Activity是用户界面的主要载体,而Context则是Android系统中的核心组件,它提供了与应用程序环境交互的能力。当我们需要在多个Activity之间传递数据时,通常会使用Intent对象,而通过...

    谈谈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的context使用

    在Android开发中,Context是一个非常核心的概念,它代表了应用程序的环境或上下文,提供了与系统服务交互的能力。本文将详细介绍Android中Context的使用,并通过一个简单的Demo展示如何在工具类和View中灵活地获取和...

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

    在Android中,如果单例持有Context的引用,特别是在使用Activity的Context时,可能会引发内存泄露。比如,一个单例类中保存了一个Activity的Context,当Activity被销毁后,由于单例的生命周期比Activity长,Activity...

    Android Context使用例子.

    1. **避免内存泄漏**:长时间持有Activity的Context会导致内存泄漏,应优先考虑使用Application Context,除非必须使用Activity的Context。 2. **生命周期管理**:了解不同类型的Context与组件的生命周期关系,避免...

    Android Context与GetApplicationContext的区别及使用1

    例如,创建单例工具类时,如果静态字段持有Activity的Context,当Activity被销毁后,单例仍然持有对Context的引用,导致Activity无法被垃圾回收,产生内存泄漏。正确的做法是使用Application的Context,或者使用弱...

    android_context详解

    `Context`类位于`frameworks/base/core/java/android/content/Context.java`,是一个抽象类,提供了诸如`getSystemService()`、`startActivity()`、`startService()`等基础API。这些方法允许开发者访问系统服务、...

    在项目的任何地方轻松获取Context的demo

    在大型项目中,过度使用Activity Context可能会导致内存泄漏,因为Activity的生命周期比Application短,持有Activity Context的引用会使得Activity无法被正确回收。因此,合理使用和管理Context至关重要。 下面是一...

    使用Android Studio检测内存泄露(LeakCanary)

    1. 避免静态变量长时间持有Activity或其他Context相关的对象,因为这可能导致Context泄露。 2. 使用WeakReference或SoftReference来弱化对象之间的引用,使得它们能够在不再被引用时被垃圾收集器清理。 3. 注意...

    Android笔记 Application对象的使用-数据传递以及内存泄漏问题

    在Android应用开发中,`Application`对象是每个应用程序的基础组件,它是所有Activity、Service等组件的顶级父类。本篇笔记将深入探讨`Application`对象的使用,包括如何利用它进行数据传递以及如何避免常见的内存...

    AndroidApp定位和规避内存泄露方法研究

    5. 使用Application Context而不是Activity Context,以减少内存泄露的风险。 6. 尽量避免在匿名内部类中直接引用外部类的非静态成员。 在Android开发过程中,掌握以上知识并付诸实践,能够有效避免内存泄露问题,...

    android中Context深入详解

    Android 中 Context 深入详解 Context 是 Android 中一个非常重要的概念,它是 Android 应用程序的核心组件之一。Context 提供了许多有用的方法和变量,用于访问应用程序的资源和组件。本文将深入探讨 Android 中 ...

    android检查内存泄露

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

    012_android 之消息提示toast 和Context

    比如,Activity的Context与应用程序的生命周期紧密相关,而Application的Context则贯穿整个应用程序的生命周期。 总结一下,本教程“012_android 之消息提示toast 和Context”将详细介绍如何在Android应用中使用...

    android内存泄露的检测和排查

    2. **静态变量和单例模式**:静态变量的生命周期与应用一致,如果它们持有Activity或Context的引用,就会导致内存泄漏。因此,避免在静态变量中保存Context的强引用。 3. **匿名内部类和非静态内部类**:这类内部类...

    反射获取Context的实例

    `Context`是Android应用的基础组件,它提供了与系统交互的各种方法,如启动Activity、发送Broadcast、访问资源等。通常,我们可以在Activity、Service或Application中直接获取`Context`实例。然而,在非UI线程或...

    通过反射获取Context实例的Demo

    在Android开发中,Context是应用程序的核心组件之一,它提供了与Android系统交互的接口,包括启动Activity、发送广播、访问资源等操作。当我们需要在非Activity或非Service类中使用Context时,可以通过各种方式获取...

    android内存的溢出和泄漏问题

    3. Activity中的生命周期对象超出Activity的生命周期:比如使用Application Context代替Activity Context,可能导致对象长时间存活,造成内存泄漏。 4. Bitmap对象未正确回收:Bitmap占用较大的内存,使用完毕后应...

Global site tag (gtag.js) - Google Analytics