zoukankan      html  css  js  c++  java
  • 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");
        }
  • 相关阅读:
    SQL学习笔记六之MySQL数据备份和pymysql模块
    SQL学习笔记五之MySQL索引原理与慢查询优化
    SQL学习笔记四之MySQL数据操作
    SQL学习笔记四(补充-2)之MySQL多表查询
    SQL学习笔记四(补充-2-1)之MySQL SQL查询作业答案
    SQL学习笔记四(补充-1)之MySQL单表查询
    SQL学习笔记四(补充-1-1)之MySQL单表查询补充部分:SQL逻辑查询语句执行顺序
    Python Web学习笔记之为什么设计GIL
    SQL学习笔记三之MySQL表操作
    buffer小解
  • 原文地址:https://www.cnblogs.com/txlbupt/p/4169076.html
Copyright © 2011-2022 走看看