On Android, aContextis used for many operations but mostly to load and access resources. This is why all the widgets receive aContextparameter in their constructor. In a regular Android application, you usually have two kinds ofContext,ActivityandApplication. It's usually the first one that the developer passes to classes and methods that need aContext:

@Override protected void onCreate(Bundle state) {  super.onCreate(state);   TextView label = new TextView(this);  label.setText("Leaks are bad");   setContentView(label); }

This means that views have a reference to the entire activity and therefore to anything your activity is holding onto; usually the entire View hierarchy and all its resources. Therefore, if you leak theContext("leak" meaning you keep a reference to it thus preventing the GC from collecting it), you leak a lot of memory. Leaking an entire activity can be really easy if you're not careful.

When the screen orientation changes the system will, by default, destroy the current activity and create a new one while preserving its state. In doing so, Android will reload the application's UI from the resources. Now imagine you wrote an application with a large bitmap that you don't want to load on every rotation. The easiest way to keep it around and not having to reload it on every rotation is to keep in a static field:

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); }

This code is very fast and also very wrong; it leaks the first activity created upon the first screen orientation change. When aDrawableis attached to a view, the view is set as acallbackon the drawable. In the code snippet above, this means the drawable has a reference to theTextViewwhich itself has a reference to the activity (theContext) which in turns has references to pretty much anything (depending on your code.)

This example is one of the simplest cases of leaking theContextand you can see how we worked around it in theHome screen's source code(look for theunbindDrawables()method) by setting the stored drawables' callbacks to null when the activity is destroyed. Interestingly enough, there are cases where you can create a chain of leaked contexts, and they are bad. They make you run out of memory rather quickly.

There are two easy ways to avoid context-related memory leaks. The most obvious one is to avoid escaping the context outside of its own scope. The example above showed the case of a static reference but inner classes and their implicit reference to the outer class can be equally dangerous. The second solution is to use theApplicationcontext. This context will live as long as your application is alive and does not depend on the activities life cycle. If you plan on keeping long-lived objects that need a context, remember the application object. You can obtain it easily by callingContext.getApplicationContext()orActivity.getApplication().

In summary, to avoid context-related memory leaks, remember the following:

  • Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
  • Try using the context-application instead of a context-activity
  • Avoid non-static inner classes in an activity if you don't control their life cycle, use a static inner class and make a weak reference to the activity inside. The solution to this issue is to use a static inner class with aWeakReferenceto the outer class, as done inViewRootand its W inner class for instance
  • A garbage collector is not an insurance against memory leaks

Note: This article was originally posted on mypersonal blog.

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. TextView 相关属性
  2. Android(安卓)技术专题系列之十一 -- DRM
  3. 在 Android 开发中使用协程 | 背景介绍
  4. [置顶] 强烈推荐转载-Android 性能测试
  5. android动态获取TextView的属性(width、he
  6. Android:style和theme
  7. Plan B:Android 的 find my phone,可事后安
  8. android 6.0 关于定位的那些坑
  9. Android数据转化为Excel表格导入导出
  10. Android 应用的版本兼容 了解一下(理解 mi