首先呢,大家可以了解一下threadLocal这个本地变量,ThreadLocal可以在不同的线程之中互不干扰地存储并提供数据,通过ThreadLocal可以轻松获取每个线程的Looper。大家只要知道这一句话就行了,也就是说threadlocal保证了一个线程唯一对应一个looper。
可见lopper在调用prepare方法的时候进行判空操作,这也就保证了一个线程唯一对应一个looper,同时看看下面looper.loop()方法可以知道其实looper内部维护了一个消息队列,looper的构造方法中传入了一个消息队列,此处的消息队列就是气构造中传入的那个,所以说线程,looper和消息队列是一一对应的,可以看到在源代码中捕获到msg后调用msg.target.dispatch()方法,其实msg. target就是发送消息的handler对象,从而保证知道是哪一个handler发过来的消息,交给对应的handler进行处理。
当我们在主线程中new handler()的时候,默认将主线程中初始化的looper对象关联到handler上,这样handler就可以处理更新ui的操作,如过我们要在子线程中创建一个handler的时候就需要在子线程中准备一个looper然后传给new 的handler,这样才可以成功在子线程中进行消息机制。
- * 初始化后台轮询线程
- */
- private void initBackThread()
- {
- // 后台轮询线程
- mPoolThread = new Thread()
- {
- @Override
- public void run()
- {
- Looper.prepare();
- mPoolThreadHandler = new Handler()
- {
- @Override
- public void handleMessage(Message msg)
- {
- // 线程池去取出一个任务进行执行
- mThreadPool.execute(getTask());
- try
- {
- mSemaphoreThreadPool.acquire();
- } catch (InterruptedException e)
- {
- }
- }
- };
- // 释放一个信号量
- mSemaphorePoolThreadHandler.release();
- Looper.loop();
- };
- };
- mPoolThread.start();
- }
其实Handler不仅可以更新UI,你完全可以在一个子线程中去创建一个Handler,然后使用这个handler实例在任何其他线程中发送消息,最终处理消息的代码都会在你创建Handler实例的线程中运行。网上就有大神利用handler写了一个图片加载类,相当牛逼。这是链接地址:http://blog.youkuaiyun.com/lmj623565791/article/details/38476887。当有任务来临时通知含有handler的子线程接受进行相应的处理,从而可以起到异步的作用
同时handler还有一个handler.post()方法,他的作用主要是处理runnable对象,但其并没有new一个线程 ,而是还是在主线程中执行,不能有太耗时的操作,如果需要可手动开启新线程。