第六章 Handler专题

2018-12-22  本文已影响0人  唔笛plk

一、什么是Handler

由于Android的只允许在UI线程(主线程)中修改UI组件,为了解决其他线程无法改变组件属性值而使用Handler类处理
作用:

二、Handler的使用

1.post(Runnable)

post方法用于handleMessage()的作用一样处理数据更新UI,源码如下,也是调用sendMessageDelayed方法,省略了很多创建Handler的代码 (适用于处理单一情况)

 /**
     * Causes the Runnable r to be added to the message queue.
     * The runnable will be run on the thread to which this handler is 
     * attached. 
     *  
     * @param r The Runnable that will be executed.
     * 
     * @return Returns true if the Runnable was successfully placed in to the 
     *         message queue.  Returns false on failure, usually because the
     *         looper processing the message queue is exiting.
     */
    public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }

2.sendMessage(Message)

sendMessage有多种发送消息的方式,有发送空数据和延迟两个属性,根据具体的情况选择和合适的方式
而且能发送不同类型消息,在handlMessage中处理。(适用于多种情况)

三、Handler内部机制

 private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
new Thread(new Runnable() {
            @Override
            public void run() {
               try {
                        Looper.prepare();
                        sendHandler = new Handler() {
                            @Override
                            public void handleMessage(Message msg) {
                                // TODO
                            }
                        };
                        Looper.loop();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }
        }).start();

Looper.loop();的作用是通过死循环的方式不断地从MessageQueen中读取消息

四、Handler引起的内存泄漏以及解决方案

原因:在java中非静态内部类和匿名内部类都会隐式持有当前类的外部引用,由于Handler是非静态内部类所以其持有当前Activity的隐式引用,如果Handler没有被释放,其所持有的外部引用也就是Activity也不可能被释放,因此造成内存泄漏。比如Hander中延迟5min发送消息,在MessaageQueen中队列中持有Hander引用,这队列间接持有Activity引用
解决办法:

  private static class MyHandler extends Handler{
        //持有弱引用HandlerActivity,GC回收时会被回收掉.
        private final WeakReference<HandlerActivity> mActivty;
        public MyHandler(HandlerActivity activity){
            mActivty =new WeakReference<HandlerActivity>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            HandlerActivity activity=mActivty.get();
            super.handleMessage(msg);
            if(activity!=null){
                //执行业务逻辑
            }
        }
    }
    private static final Runnable myRunnable = new Runnable() {
        @Override
        public void run() {
            //执行我们的业务逻辑
        }
    };
 

五、如何使用Handler让子线程与子线程之间进行通信

1.创建两个子线程,分别在子线程内创建Hander对象
2.分别在子线程内发送消息

上一篇 下一篇

猜你喜欢

热点阅读