• android 中handler的用法分析


    1、直接再ui线程中初始化,这种情况handlermessage会在 ui线程中执行

    2、传入Looper 参数,这种情况会在ht线程中执行 handlermessage。

    HandlerThread ht = new HandlerThread("handler");
    ht.start();
    Handler handler = new Handler(ht.getLooper());

    步骤分析:

    1、HandlerThread 继承Thread

     public void run() {
            mTid = Process.myTid();
            Looper.prepare();
            synchronized (this) {
                mLooper = Looper.myLooper();
                notifyAll();
            }
            Process.setThreadPriority(mPriority);
            onLooperPrepared();
            Looper.loop();
            mTid = -1;
        }

    2、在run 分别初始化 ,绑定Looper 到当前线程,并且执行looper 循环处理MessageQuene 中的message

    //初始化Looper
    a) Looper.prepare(); b) if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); c) private Looper() { mQueue = new MessageQueue(); mRun = true; mThread = Thread.currentThread(); } //绑定 Looper 到当前线程 a) sThreadLocal.set(new Looper()); b) public void set(T value) { Thread currentThread = Thread.currentThread(); //取出当前线程中的ThreadLocal.Values变量 Values values = values(currentThread); if (values == null) { values = initializeValues(currentThread); } //将Looper变量保存到ThreadLocal.Values 变量中 values.put(this, value); } c) Values values(Thread current) { return current.localValues; } //循环处理Message Looper.looper()

    所以线程ht.getLooper() 可以用 ThreadLocal 从 当前线程中获取 Looper

    3 、Handler 中的MessageQuene 为 Looper中 MessageQuene 的引用 ,sendmessage将Message保存到 MessageQuene,然后 再loop中取用。

    public boolean sendMessageAtTime(Message msg, long uptimeMillis)
        {
            boolean sent = false;
            MessageQueue queue = mQueue;
            if (queue != null) {
                msg.target = this;
                sent = queue.enqueueMessage(msg, uptimeMillis);
            }
            else {
                RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
                Log.w("Looper", e.getMessage(), e);
            }
            return sent;
        }

     Handler 另外用法 在service(或者非UI线程)中调用Toast等UI操作

    looper = Looper.getMainLooper();
    handler = new Handler(looper);
    handler.post(new Runnable()
    {
       public void run()
       {
           Toast.makeText().show();  
       }
    });

    同样可以使用Activity.runOnUiThread(Runnable r);
  • 相关阅读:
    适合程序员的两样工具-续集
    JavaScript之面向对象1
    人类简史笔记摘录
    做正确的事
    个人高效率任务列表
    视频技术基础
    了解更多梭罗与瓦尔登湖
    禅与摩托车维修的艺术
    人工智能发展及算法
    互联网没能降低房价,人工智能就可以不?
  • 原文地址:https://www.cnblogs.com/lipeil/p/2617012.html
Copyright © 2020-2023  润新知