zoukankan      html  css  js  c++  java
  • WeakReference在Handler中的应用

     1 public class AutoActivity extends Activity {
     2 
     3     Handler handler = new Handler(){
     4         public void handleMessage(android.os.Message msg) {
     5             
     6         };
     7     };
     8     @Override
     9     protected void onCreate(Bundle savedInstanceState) {
    10         super.onCreate(savedInstanceState);
    11         setContentView(R.layout.activity_auto);
    12     }
    13 }

      上面这段代码在handler对象创建的时候却会报警告:This Handler class should be static or leaks might occur。意思是:Handler

    类应该为static类型,否则可能会造成内存泄漏。

      为什么会造成这种情况呢?

      这种情况就是由于android的特殊机制造成的:当一个android主线程被创建的时候,同时会有一个Looper对象被创建,而这个Looper对象会实现一个MessageQueue(消息队列),当我们创建一个handler对象时,而handler的作用就是放入和取出消息从这个消息队列中,每当我们通过handler将一个msg放入消息队列时,这个msg就会持有一个handler对象的引用。因此当Activity被结束后,这个msg在被取出来之前,这msg会继续存活,但是这个msg持有handler的引用,而handler在Activity中创建,会持有Activity的引用,因而当Activity结束后,Activity对象并不能够被gc回收,因而出现内存泄漏。

      这个根本原因就是:Activity在被结束之后,MessageQueue并不会随之被结束,如果这个消息队列中存在msg,则导致持有handler的引用,但是又

    由于Activity被结束了,msg无法被处理,从而导致永久持有handler对象,handler永久持有Activity对象,于是发生内存泄漏。但是为什么为static类型就

    会解决这个问题呢?因为在java中所有非静态的对象都会持有当前类的强引用,而静态对象则只会持有当前类的弱引用。声明为静态后,handler将会持

    有一个Activity的弱引用,而弱引用会很容易被gc回收,这样就能解决Activity结束后,gc却无法回收的情况。

    所以解决这个警告就有几种方法:

    一:将hanlder对象声明为静态的对象。

    二:使用静态内部类,通过WeakReference实现对Activity的弱引用。具体实现看以下代码:

     1 public class AutoActivity extends Activity {
     2     
     3     MyHandler handler = new MyHandler(this);
     4     @Override
     5     protected void onCreate(Bundle savedInstanceState) {
     6         super.onCreate(savedInstanceState);
     7         setContentView(R.layout.activity_auto);
     8     }
     9     
    10     static class MyHandler extends Handler{
    11         WeakReference<AutoActivity> mactivity;
    12         
    13         public MyHandler(AutoActivity activity){
    14             mactivity = new WeakReference<AutoActivity>(activity);
    15         }
    16         
    17         @Override
    18         public void handleMessage(Message msg) {
    19             super.handleMessage(msg);            
    20             switch (msg.what) {
    21             case 100:                
    22                 //在这里面处理msg
    23                 //通过mactivity.get()获取Activity的引用(即上下文context)
    24                 break;                
    25             default:
    26                 break;
    27             }
    28         }
    29     }
    30 }

    转自:https://my.oschina.net/u/1177694/blog/523922

  • 相关阅读:
    learnyou 相关网站
    hdu 3038 How Many Answers Are Wrong
    hdu 3047 Zjnu Stadium 并查集高级应用
    poj 1703 Find them, Catch them
    poj 1182 食物链 (带关系的并查集)
    hdu 1233 还是畅通工程
    hdu 1325 Is It A Tree?
    hdu 1856 More is better
    hdu 1272 小希的迷宫
    POJ – 2524 Ubiquitous Religions
  • 原文地址:https://www.cnblogs.com/l2rf/p/6047073.html
Copyright © 2011-2022 走看看