多线程通讯之Handler实现

在Android系统中,多线程之间传递消息我们可以用Handler来实现

UI线程向子线程发送消息,子线程接收到消息后处理

public class MainToWorkThreadActivity extends Activity {
    private Handler handler;
    private Button button1;

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

        button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // 在主线程发送消息
                System.out.println("onClick: "
                        + Thread.currentThread().getName());
                Message msg = handler.obtainMessage();
                msg.what = 100;
                handler.sendMessage(msg);

            }
        });

        new Thread() {

            @Override
            // 在线程中处理主线程发送的消息对象
            // 为什么工作线程中需要Looper对象,而主线程不需要??
            public void run() {
                // 准备Looper对象
                Looper.prepare();
                // 在WorkThread当中生成一个Handler对象
                handler = new Handler() {

                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        System.out.println("handleMessage: " + Thread.currentThread().getName());
                    }
                };
                // 调用Looper的loop()方法之后,Looper对象将不断的从消息队列中取出消息对象,
                // 然后调用handlerMessage()方法处理该消息对象
                // 如果消息队列中没有对象,则该线程阻塞
                Looper.loop();
            }
        }.start();
    }
}

子线程向UI线程发送消息,UI线程接收消息后处理

public class WorkToMainThreadActivity extends Activity {
    private Button button1, button2, button3;
    private ProgressBar progressBar;
    private Handler handler;

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

        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);
        button3 = (Button) findViewById(R.id.button3);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setMax(100);

        /*
         * 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;
         * Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()
         * 方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。 两种实现方式的区别和联系:
         *
         * 在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:
         * 1.避免点继承的局限,一个类可以继承多个接口。 2.适合于资源的共享
         */
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 继承Thread方法实现多线程
                new Thread() {
                    @Override
                    public void run() {
                        System.out.println("button1.onClick.run: " + Thread.currentThread().getId()+ Thread.currentThread().getName());
                        try {
                            int i = 5;
                            while (i <= 100) {
                                sleep(500);
                                Message msg = handler.obtainMessage();
                                msg.arg1 = i;
                                handler.sendMessage(msg);
                                // 上面一行代码将消息对象放置到消息队列当中
                                // 1.Looper将会从消息队列当中将消息对象取出
                                // 2.Looper将会找到与消息对象对应的Handler对象
                                // 3.Looper将会调用handler对象的handleMessage(Message msg)方法,用于处理消息对象
                                i += 5;
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        super.run();
                    }
                }.start();
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                 * 在实际开发中一个多线程的操作很少使用Thread类,而是通过Runnable接口完成。
                 * 但是在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。
                 * 此时观察Thread类,有一个构造方法:public Thread(Runnable targer)此构造方法接受Runnable的子类实例,
                 * 也就是说可以通过Thread类来启动Runnable实现的多线程。(start()可以协调系统的资源)
                 */
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("button2.onClick.run: " + Thread.currentThread().getId()+ Thread.currentThread().getName());
                        try {
                            int i = 10;
                            while (i <= 100) {
                                Thread.sleep(1000);
                                Message msg = handler.obtainMessage();
                                msg.arg1 = i;
                                handler.sendMessage(msg);
                                i += 10;
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        });

        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                 * Runnable对象和主用户界面线程的ID是相同。在这个例子中,我们直接利用handler对象post了一个runnable对象
                 * ,相当于直接调用了Runnable对象的run函数,也就说没有经过start函数调用run(),那么就不会创建一个新线程,
                 * 而是在原有线程内部直接调用 run()方法,因此输出的线程Id是相同的。
                 */
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("button3.onClick.run: " + Thread.currentThread().getId()+ Thread.currentThread().getName());
                        try {
                            int i = 1;
                            while (i <= 100) {
                                Thread.sleep(100);
                                Message msg = handler.obtainMessage();
                                msg.arg1 = i;
                                handler.sendMessage(msg);
                                i += 1;
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        });

        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // 在主线程处理消息,工作线程发送消息,以方便线程间通信
                // 这样可以解决工作线程不能操作UI的问题
                System.out.println("handleMessage: " + Thread.currentThread().getId() + Thread.currentThread().getName());
                progressBar.setProgress(msg.arg1);
                super.handleMessage(msg);
            }
        };
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值