Handler入门(1)

一:简单用

1.0:用法

   @SuppressLint("HandlerLeak")
        Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case 1:
                        Log.i("MainActivity",msg.toString());
                        //TODO
                        break;
                }
            }
        };

        Message mMessage = Message.obtain();
        mMessage.what = 1;//标志
        mMessage.obj = "data";
        mHandler.sendMessage(mMessage);

注:Message mMessage = Message.obtain();,为啥这样写,看法宝

 /**
     * Return a new Message instance from the global pool. Allows us to
     * avoid allocating new objects in many cases.
     */
    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

打印输出结果

MainActivity: { when=-24ms what=1 obj=data target=com.practicing.demo.MainActivity$1 }

二:优化

2.1.容易引起的问题

2.1.1 内存泄露

非静态内部类可以直接访问外部类的成员,反之不行。因为非静态内部类没有被static修饰,所以这个内部类就不是类相关的,也就说不是类的,是实例的,但是我们非静态内部类要创建实例,外部类一定会先创建一个外部类的实例,非静态内部类的实例就是寄生在外部类的实例上的。所以,非静态内部类的实例可以直接访问外部类的成员,因为,外部类已经创建一个实例的,内部类保留了外部类创建的实例的引用。静态内部类不一样!静态内部类是被static修饰的,所以是类的一员。根据静态成员不能访问非静态成员的原则,静态内部类是不能访问外部类的非静态成员的。非静态的内部类和匿名内部类都会隐式地持有其外部类的引用。一般情况会把Handler写成静态内部类。如果为非静态内部类,会引用外部类对象。Handler被Activity引用,当Activity finish以后,Handler仍未执行完毕,就会造成内存泄露。这就是 非静态内部类引用外部类对象造成内存泄露

2.1.2 空指针异常

Activity 调用destory()方法之后,Handler的相关资源仍违背释放,然后就空指针喽

2.2:解决办法

2.2.1 内存泄露

  • 放在单独的类中
    这个没啥说的,就是创建一个新的类
  • 弱引用
 public  class MyHandler extends Handler{
        private final WeakReference<MainActivity> activityWeakReference;

        public MyHandler(MainActivity activity) {
            activityWeakReference = new WeakReference<MainActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            if (activityWeakReference.get() != null){
                switch (msg.what) {
                    case 1:
                        Log.i("MainActivity","activityWeakReference:"+msg.toString());
                        //TODO
                        break;
                }
            }
        }
    }

调用部分

 MyHandler myHandler = new MyHandler(this);
        Message mMessageWeak = Message.obtain();
        mMessageWeak.what = 1;
        mMessageWeak.obj = "MyHandler";
        myHandler.sendMessage(mMessageWeak);

2.2.2 空指针异常

把消息队列中的消息remove掉,具体做法就是在onDestroy()方法里面,调用removeCallbacks()方法,removeMessage()方法.

猜你喜欢

转载自blog.csdn.net/MyheartMylove/article/details/81665200
今日推荐