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

  • 相关阅读:
    HDU 1269 迷宫城堡
    HDU 4771 Stealing Harry Potter's Precious
    HDU 4772 Zhuge Liang's Password
    HDU 1690 Bus System
    HDU 2112 HDU Today
    HDU 1385 Minimum Transport Cost
    HDU 1596 find the safest road
    HDU 2680 Choose the best route
    HDU 2066 一个人的旅行
    AssetBundle管理机制(下)
  • 原文地址:https://www.cnblogs.com/l2rf/p/6047073.html
Copyright © 2011-2022 走看看