zoukankan      html  css  js  c++  java
  • Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)

    keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)


    相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况。

    本文主要研究Handler的消息发送。

    包含主线程往子线程发送消息,子线程之间互相发送消息。


    一、主线程向子线程发送消息。


    实现过程比較简单:


    主线程发送消息到异步线程。异步线程接收到消息后在再发送一条消息给主线程。


    1. 初始化主线程的Handler,用来接收子线程的消息。

    2. 启动异步线程。在异步线程中创建Looper,并初始化一个异步线程的Handler。

    3. 主线程获取异步线程的Handler(这里涉及到线程间同步的知识)。并向异步线程发送消息。

    4. 异步线程Handler接收到消息以后,获取主线程的Handler,并向主线程发送消息。

    5. 主线程收到异步线程发来的消息。


    注:

    1. 这里说的主线程Handler或者异步线程Handler,指的是绑定在相应线程消息队列上的一个Handler对象而已,在Handler的构造函数中传入相应线程的Looper对象就可以。

    2. 为什么要使用线程锁来处理,是由于异步线程启动不是实时的。主线程获取异步线程的Handler时有可能为空,假设为空,须要等待异步线程先初始化Handler。


    上代码:

    package com.example.chen.myapplication;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Looper;
    import android.os.Message;
    import android.util.Log;
    
    /**
     * 用Handler測试主线程往子线程发送消息
     * @author chen
     */
    public class HandlerSimpleActivity extends Activity {
    
        private Handler mainHandler;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // 启动异步线程
            final AsyncThread asyncThread = new AsyncThread();
            asyncThread.start();
    
            // 初始化主线程的Handler
            mainHandler = new Handler(Looper.myLooper(), new Handler.Callback() {
                @Override
                public boolean handleMessage(Message msg) {
                    // 主线程收到消息
                    Log.e(HandlerSimpleActivity.class.getSimpleName(),
                            "MainHandler Receiver Message curThread = "
                                    + Thread.currentThread().getName());
                    return false;
                }
            });
    
    
            // 获取异步线程的Handler
            Handler handler = asyncThread.getHandler();
            if (handler != null) {
                Log.e(HandlerSimpleActivity.class.getSimpleName(),
                        "MainThread Send Message curThread = "
                                + Thread.currentThread().getName());
                // 向异步线程发送消息
                handler.sendEmptyMessage(0);
            }
    
        }
    
        /**
         * 异步线程
         */
        private class AsyncThread extends Thread {
    
            private Handler handler;
    
            @Override
            public void run() {
                super.run();
                Log.e(HandlerSimpleActivity.class.getSimpleName(),
                        "AsyncThread Start curThread = "
                                + Thread.currentThread().getName());
    
                Looper.prepare();  // 初始化异步线程的消息循环队列
    
                if (handler == null) {
                    synchronized (AsyncThread.class) { // 线程间安全
                        // 为异步线程的消息循环队列新增一个Handler
                        handler = new Handler(Looper.myLooper(), new Handler.Callback() {
                            @Override
                            public boolean handleMessage(Message msg) {
                                // 异步线程收到消息
                                Log.e(HandlerSimpleActivity.class.getSimpleName(),
                                        "AsyncHandler Receiver Message curThread = "
                                                + Thread.currentThread().getName());
    
                                // 异步线程发送消息到主线程
                                Log.e(HandlerSimpleActivity.class.getSimpleName(),
                                        "AsyncThread Send Message curThread = "
                                                + Thread.currentThread().getName());
                                mainHandler.sendEmptyMessage(0);
                                return false;
                            }
                        });
    
                        // 异步线程Handler初始化完成
                        Log.e(HandlerSimpleActivity.class.getSimpleName(),
                                "AsyncHandler Inited curThread = "
                                        + Thread.currentThread().getName());
    
                        // 释放锁
                        AsyncThread.class.notifyAll();
                    }
                }
    
                Looper.loop();
            }
    
            /**
             * 获取异步线程的Handler
             * @return
             */
            public Handler getHandler() {
                if (handler == null) {
                    synchronized (AsyncThread.class) {  // 线程间安全
                        if (handler == null) {
                            try {
                                // 获取异步线程的handler为空。释放锁,等待异步线程初始化完成。

    Log.e(HandlerSimpleActivity.class.getSimpleName(), "getHandler wait curThread = " + Thread.currentThread().getName()); AsyncThread.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } // 异步线程Handler初始化完成。主线程继续 Log.e(HandlerSimpleActivity.class.getSimpleName(), "getHandler notified curThread = " + Thread.currentThread().getName()); return handler; } else { return handler; } } } else { return handler; } } } }


    上结果截图:



    二、子线程间使用Handler互相发送消息:


    2015年7月26日19:47:31   等待下次更新(*^__^*) 嘻嘻……


    2015年11月9日更新。线程间通信能够用HandlerThread。有兴趣的朋友能够看看源代码。就一个类。代码也不多,系统的API写的要健壮一些。

    关于HandlerThread。大家能够阅读该片博客:

    http://blog.csdn.net/a740169405/article/details/50257001


    本人Android菜鸟,尽请指正!!


  • 相关阅读:
    NOIP 2011 DAY 2
    NOIP 2011 DAY 1
    扩展欧几里得算法(exgcd)
    中国剩余定理
    线性同余方程的求解
    乘法逆元
    poj 1845 Sumdiv(约数和,乘法逆元)
    欧拉-费马小定理定理(证明及推论)
    求解范围中 gcd(a,b)== prime 的有序对数
    KindEditor解决上传视频不能在手机端显示的问题
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/6764490.html
Copyright © 2011-2022 走看看