Android的handler机制理解

1、Handler机制是Android提供的一种异步回调机制,在Ui线程中使用handler需要new一个handler对象,并重写其中的handleMessage(Message msg)方法,处理如更新UI等操作。
    private Handler handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            //to do
        }
    };

然后在异步线程中调用hanlder.sendMessage(Message msg)告诉UI线程去更新UI等操作。

从原理上来讲,使用了Hanlder对象的线程需要绑定一个Looper对象,该对象维护一个消息队列,Looper对象取出该队列的消息后交由handler进行处理。所以在使用Handler时,要调用Looper.prepare()方法给当前的线程绑定一个Looper对象。
    
    public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

然后调用loop()建立对消息队列的循环,在消息队列中取出消息后交由相应的handler进行处理。由于一个线程中可能有多个handler,为了区分这些不同的hanlder所需要处理的消息,每个Message对象都维护有一个hanlder实例即target,在loop方法中通过调用msg.target.dispatchMessage(msg)进行处理。

每个线程只能绑定一个loop对象,多个handler共享,handler的在构造时从当前的线程中取得loop对象,Looper中的myLooper中返回了sThreadLocal.get()所取得的Looper对象

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;

所以,在使用handler中需要执行以下步骤,首先调用Looper.prepare()方法为当前线程绑定Looper对象,然后才可以实例化一个Handler对象,最后调用loop()方法建立消息循环

 class LooperThread extends Thread {
        public Handler mHandler;
  
        public void run() {
            Looper.prepare();
  
            mHandler = new Handler() {
                public void handleMessage(Message msg) {
                    // process incoming messages here
                }
            };
            Looper.loop();
        }
    }

在很多情况下我们在activity或者其他场合中使用Handler进行异步消息处理,并没有显式地声明绑定一个Looper对象。这是因为主线程它已经绑定了一个Looper对象

    public static final void main(String[] args) {
        SamplingProfilerIntegration.start();

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        Looper.loop();

        if (Process.supportsProcesses()) {
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }

        thread.detach();
        String name = (thread.mInitialApplication != null)
            ? thread.mInitialApplication.getPackageName()
            : "<unknown>";
        Slog.i(TAG, "Main thread of " + name + " is now exiting");
    }

 

posted on 2014-12-17 12:18  止宇  阅读(5300)  评论(0编辑  收藏  举报

导航