浅析android线程处理和通信

 

浅析android线程处理和通信

浅析android线程处理和通信
做过java的朋友应该对java的线程类Thread很熟悉了,用法也很简单直观,简单写个最简单的例子:
public class A implements Runnable {
    @Override
    public void onCreate() {
     //创建工作线程
     Thread thread = new Thread(this);
     thread.start();
    }
    @Override
    public void run() {
     //工作线程
}
}

在创建完thread,并把thread start以后,一个新的线程就开始调用run方法运行了。
原本这样就够用了,可是Android还是害怕我们用起来不方便,又提供了几个类让大家用起来更舒服,唉,没办法,谁让Android的架构中设计了那么多异步调用的方法呢。

这几个类包括:Handler、Looper和HandlerThread,要承认刚看到这三个玩艺很快调用的时候,我很快就有些晕了,SDK文档上的说明看了半天,明白了大体的工作方式,但就是总觉得不踏实,最后没办法,拉下这部分的源代码把这部分看了一下,才算是心里有了底。
先写一个这三个类常用的使用方法,看看能不能把你搞晕。

HandlerThread thread = new HandlerThread();
thread.start();
Looper looper = thread.getLooper();
Handler handler = new = new Handler(looper) {
        @Override
        public void handleMessage(Message msg) {
         //消息处理
        }
    };
    
    ....
    //其他线程向thread线程发送消息
    handler.sendEmptyMessage(0);

    
晕了也没事,看了我下面的话,应该能清醒个七七八八,如果再整不明白,就和我一样去看source吧。先从HandlerThread说起,这个类是继承自Thread,不过在调用的时候可就不一样了。Thread在构造的时候需要传递一个实现了Runnable接口的对象,当线程开始运行的时候,就会执行这个对象的run方法,可HandlerThread不需要你传递这个对象,因为它自己实现了这个run的方法,当线程创建运行的时候HandlerThread会执行自己的run.当然HandlerThread也不会白收钱不办事的,他会返回给你一个信物,就是Looper,用HandlerThread.getLooper的方法就可以。
先看一下HandlerThread的run中的代码,mLooper就是要返回给我们的信物了。而程序执行时会在Looper.loop()中不停的loop,直到执行Looper.quit方法。
    
public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            Process.setThreadPriority(mPriority);
            notifyAll();
        }
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

    

Looper这东西基本上可以当他是一个被动的数据类型,主要的用途就是为一个线程做标示,确切的来说他包装了一个消息队列。每个线程都会唯一对应一个Looper对象,有了Looper以后我们还没有办法直接用,我们就可以用Handler来传递消息了,Handler构造的时候需要一个Looper做为参数,当然你不给他也可以,他会默认得到当前执行线程的Looper。这个handler构造好以后,就算是大功告成了,任何线程拿到这个handler都可以向这个线程发消息,这个消息是一个异步消息,执行完sendMessage方法以后会立即返回,而looper的属主线程就会来执行handler的handleMessage方法。如果上面说的还不够清楚,我们来看一下loop方法的实现:
    
public static final void loop() {
        Looper me = myLooper();
        MessageQueue queue = me.mQueue;
        while (true) {
            Message msg = queue.next(); // might block
            //if (!me.mRun) {
            //    break;
            //}
            if (msg != null) {
                if (msg.target == null) {
                    // No target is a magic identifier for the quit message.
                    return;
                }
                if (me.mLogging!= null) me.mLogging.println(
                        ">>>>> Dispatching to " + msg.target + " "
                        + msg.callback + ": " + msg.what
                        );
                msg.target.dispatchMessage(msg);
                if (me.mLogging!= null) me.mLogging.println(
                        "<<<<<> 
                        + msg.callback);
                msg.recycle();
            }
        }
    }

在loop循环的时候会从队列中读取消息,当然即使队列中没有消息Looper也不会空循环,而是会block住,等有消息的时候会去调用消息target也就是handler的dispatchMessage方法,再由dispatchMessage将消息交给handleMessage执行。习惯hack代码的xd看到这里可能就会有想法,如果我在传递消息的时候把msg的target指定为其他的handler那样会不会就交给了其他的处理程序去处理,这部分Android已经给你处理掉了,在执行Handler的sendMessage的方法中都已经替你把msg的target填入了正确的值,所以这部分大可以放心使用。

这几个组件类似于Android提供的增值服务,如果你还是使用以往Java的Thread类的调用方式,在Android下也没什么问题。虽然这几个东西搞的比较复杂,但如果明白其中的实现原理,用起来还是挺方便的,起码一个完善的消息队列内部已经替你实现好了。Android内部也大都使用的这种实现方式,所以还是推荐大家尝试一下。

java代码在core目录下
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值