Android的消息机制(二) 之 Looper的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lyz_zyx/article/details/80543787

简介

我们在上篇文章《Android的消息机制》中提到,线程默认是没有Looper的,只能向存在Looper的线程发消息,否则会抛RuntimeException异常。所以我们也知道主线程在被创建时就创建了Looper。今天我们继续来讲讲消息机制中Looper在主线程中是怎样被创建 和 我们自己创建的子线程中能否也创建Looper来接收消息。

主线程的消息循环

Android的主线程就是ActivityThread,ActivityThread中的入口方法Main(),该方法下你会发现有:Looper.prepareMainLooper() 和 Looper.loop()两行代码。其中,prepareMainLooper方法是prepare的封装。上一篇文章中提到过,通过Looper.prepare()即可为当前线程创建一个Looper,接着通过Looper.loop()来开启消息循环。所以ActivityThread中的Main方法源码如下所示:

public static void main(String[] args) {
    SamplingProfilerIntegration.start();
    …
    Process.setArgV0("<pre-initialized>");
    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler== null) {
        sMainThreadHandler= thread.getHandler();
    }
    AsyncTask.init();
    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

子线程中Looper的创建和使用

虽然我们知道了要使用handler就必须在接收线程中存在Looper,而创建Looper的过程也在ActivityThread源码中查阅到。所以接下来,我们通过Demo来验证子线程接收消息是如何做的,代码如下:

public class MainActivity extends AppCompatActivity {

    private  final static int MSG_SCAN_START = 0;
    private  final static int MSG_SCAN_END = 1;

    private LooperThread mLooperThread;

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

        mLooperThread= new LooperThread("looperThread");
        mLooperThread.start();

        new Thread("Thread1") {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000); // 为了要让LooperThread都初始化完成,这里等待1秒钟

                    mLooperThread.mHandler.sendEmptyMessage(MSG_SCAN_START);

                    Thread.sleep(1000);

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    Message msg = mLooperThread.mHandler.obtainMessage();
                    msg.what= MSG_SCAN_END;
                    msg.obj = true;
                    mLooperThread.mHandler.sendMessage(msg);
                }

                // 这是通过post发消息
                mLooperThread.mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.e("zyx", "线程名:" + Thread.currentThread().getName() + ",这是通过post发的消息");
                    }
                });
            }

        }.start();
    }

    class LooperThread extends Thread {
        public Handler mHandler;

        public  LooperThread(String threadName) {
            super(threadName);
        }

        public void run() {
            Looper.prepare();

            mHandler= new Handler() {
                public void handleMessage(Message msg) {

                    int what = msg.what;
                    Object obj = msg.obj;
                    switch (what) {
                        case MSG_SCAN_START:
                            Log.e("zyx", "线程名:" + Thread.currentThread().getName() + ",OnScanStart");
                            break;
                        case MSG_SCAN_END:
                            booleanresult = (boolean)obj;
                            Log.e("zyx", "线程名:" + Thread.currentThread().getName() + ",OnScanEnd:" + result);
                            break;
                    }
                }
            };
            Looper.loop();
        }
    }
}

代码相对比较简单,在Thread1线程中,为了让LooperThread能初始化完成,所以特意做了1秒钟的等待,然后分别用:sendEmptyMessage、sendMessage 和 post三种方式发出了3个消息,我们一起来看看输出结果:

D/zyx: 线程名:looperThread,OnScanStart

D/zyx: 线程名:looperThread,OnScanEnd:true

D/zyx: 线程名:looperThread,这是通过post发的消息

 

 

 

猜你喜欢

转载自blog.csdn.net/lyz_zyx/article/details/80543787