Android编程基础之消息处理机制的简单实现

Android通过Looper、Handler来实现消息循环机制。Android的消息循环是针对线程的,每个线程都可以有自己的消息队列和消息循环。本文通过几个简单的例子来说明一下Android消息机制的基本使用方法。(本文所有的例子都是基于Android Studio 2.2.3)


一、自定义消息处理机制

首先定义一个子线程,实现消息队列和消息循环,这个子线程的具体实现如下:

 /* 定义一个子线程,实现消息队列和消息循环 */
    class MyThread extends Thread{

        private Looper looper = null;

        @Override
        public void run() {
            super.run();
            Looper.prepare();       // 创建消息队列

            /* 同步代码块,获得当前线程的Looper对象 */
            synchronized (this){
                looper = Looper.myLooper();
                notifyAll();
            }
            Looper.loop();          // 进入消息循环
        }

        public Looper getLooper(){
            if (!isAlive()) {
                return null;
            }
            // If the thread has been started, wait until the looper has been created.
            synchronized (this) {
                while (isAlive() && looper == null) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            return looper;
        }

    }
并在这个子线程中实现了一个public方法getLooper(),用来和具体的handler进行绑定。在主线程中添加一个按钮,每次按下按钮就向子线程发送一条消息,整个例子完整的代码如下所示:

package cn.edu.syau.yl_app_handler_msg;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private final String KEY = "MESSAGE";

    private Button button = null;
    private MyThread thread = null;
    private Handler handler = null;

    /* 定义一个子线程,实现消息队列和消息循环 */
    class MyThread extends Thread{

        private Looper looper = null;

        @Override
        public void run() {
            super.run();
            Looper.prepare();       // 创建消息队列

            /* 同步代码块,获得当前线程的Looper对象 */
            synchronized (this){
                looper = Looper.myLooper();
                notifyAll();
            }
            Looper.loop();          // 进入消息循环
        }

        public Looper getLooper(){
            if (!isAlive()) {
                return null;
            }
            // If the thread has been started, wait until the looper has been created.
            synchronized (this) {
                while (isAlive() && looper == null) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            return looper;
        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.btnSend);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message = handler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putString(KEY, "TECH-PRO!");
                message.setData(bundle);
                handler.sendMessage(message);

                System.out.println("main to child : send a message!");

            }
        });

        /* 启动子线程,进行消息循环,接收主线程发送过来的消息 */
        thread = new MyThread();
        thread.start();

        /* 将这个handler和子线程进行绑定,处理子线程接收到的消息 */
        handler = new Handler(thread.getLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                Bundle bundle = msg.getData();
                String string = bundle.getString(KEY);

                System.out.println("child from main : " + string);

                return false;
            }
        });
    }
}
编译运行,结果如下:



二、实现主线程向子线程发送消息

实现和上面同样的功能,但是使用系统自带的HandlerThread类,它里面已经创建了消息队列并且实现了消息循环,使用起来简单高效,完整的测试代码如下所示:

package cn.edu.syau.yl_app_handler_msg;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private final String KEY = "MESSAGE";

    private Button button = null;
    private HandlerThread handlerThread = null;
    private Handler handler = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.btnSend);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message = handler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putString(KEY, "TECH-PRO!");
                message.setData(bundle);
                handler.sendMessage(message);

                System.out.println("main to child : send a message!");

            }
        });

        /* 启动子线程,进行消息循环,接收主线程发送过来的消息 */
        handlerThread = new HandlerThread("TECH-PRO");
        handlerThread.start();

        /* 将这个handler和子线程进行绑定,处理子线程接收到的消息 */
        handler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                Bundle bundle = msg.getData();
                String string = bundle.getString(KEY);

                System.out.println("child from main : " + string);

                return false;
            }
        });
    }
}


编译并运行结果如下:


三、实现子线程向主线程发送消息

实现和上面例子相反的功能,因为在Android的主线程或者UI线程中已经默认创建了消息队列,并且实现了消息循环,所以只需要只需要将消息处理handler与主线程进行绑定就可以处理主线程的消息了。为了实现这个功能,还需要实现一个子线程向主线程发送消息,这个子线程的具体实现如下:

 /* 定义一个子线程用于发送消息 */
    class MyThread extends Thread{
        @Override
        public void run() {
            for(;;) {
                Message message = myHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putString(KEY, "TECh-PRO!");
                message.setData(bundle);
                myHandler.sendMessage(message);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("child to main : send a message!");
            }
        }
   }


整个例子的完整代码如下所示:

package cn.edu.syau.yl_app_handler_msg;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private final String KEY = "TECH-PRO";

    private MyHandler myHandler = null;
    private MyThread myThread = null;

    /* 定义一个handler用来处理子线程发给主线程的消息 */
    class MyHandler extends Handler{
        public MyHandler(){}
        public MyHandler(Looper looper){super(looper);}

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            Bundle bundle = msg.getData();
            String string = bundle.getString(KEY);
            System.out.println("main from child : " + string);
        }
    }

    /* 定义一个子线程用于发送消息 */
    class MyThread extends Thread{
        @Override
        public void run() {
            for(;;) {
                Message message = myHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putString(KEY, "TECh-PRO!");
                message.setData(bundle);
                myHandler.sendMessage(message);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("child to main : send a message!");
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /* 将主线程和handler消息处理绑定在一起 */
        myHandler = new MyHandler(MainActivity.this.getMainLooper());

        myThread = new MyThread();
        myThread.start();
    }
}
编译运行,结果如下:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值