您的位置:首页 > 其它

说说内存泄露那点事

2015-04-10 11:32 351 查看


说说内存泄露那点事

2013-05-09 19:21 by HalZhang, 840 阅读, 2 评论, 收藏, 编辑

先看看一个例子:

1 private static Drawable sBackground;
2
3 @Override
4 protectedvoid onCreate(Bundle state){
5   super.onCreate(state);
6
7   TextView label =newTextView(this);
8   label.setText("Leaks are bad");
9
10   if(sBackground ==null){
11     sBackground = getDrawable(R.drawable.large_bitmap);
12   }
13   label.setBackgroundDrawable(sBackground);
14
15   setContentView(label);
16 }
17


上面几行代码,内存泄露挺严重的。sBackground是一个 static 变量,在 label调用setBackgroundDrawable的时候,会调用sBackground的setCallback,所以在sBackground中就存在label的引用。
而,label中又存在Activity的引用,所以此Activity一直不会被回收,即使已经finish了。
如何避免:

使用applicationContext作为上下文,避免使用activity
设置Drawable的Callback为null
在Service或者Activity使用内部类尽量使用static类。例如:使用Handler

关于第3点,看个例子:

1    static class IncomingHandlerextendsHandler {
2         private final WeakReference<UDPListenerActivity> mActivity;
3
4         IncomingHandler(UDPListenerActivity activity) {
5             mService = newWeakReference < UDPListenerActivity > (activity);
6         }
7
8         @Override
9         public void handleMessage(Message msg) {
10             UDPListenerActivity activity = mActivity.get();
11             if (activity != null) {
12                 activity.handleMessage(msg);
13             }
14         }
15    }


我们知道,Message发出之后是存在MessageQueue中的,有些Message也不是马上就被处理的。在Message存在一个 target,是Handler的一个引用,如果Message在Queue中存在的时间越长,就会导致Handler无法被回收。如果Handler是非静态的,则会导致Activity或者Service不会被回收。
所以正确处理Handler等之类的内部类,应该采用上述代码。

参考:
http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler

http://android-developers.blogspot.jp/2009/01/avoiding-memory-leaks.html

-----END-----
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: