android 37 线程通信Looper


安卓程序的主线程也叫UI线程。

 

工作线程和主线程的差别:安卓主线程已经调用了Looper.prepare()方法了,已经有一个MessageQueue对象了,所以才可以在工作线程用Handler发消息到主线程:因为主线程有消息队列,发的消息都存在队列里面,并且主线程已经有Looper进行取消息了。
自己创建的工作线程是没有MessageQueue和Looper,所以不能向工作线程发消息,因为没有存消息的地方和取消息的东西。但是他可以有MessageQueue和Looper。

MessageQueue是消息队列,Looper轮训从消息队列中取消息,Handler用于发送和处理消息。

mainActivity:

package com.sxt.day06_02;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    ProgressBar mProgressBar;
    TextView mtvProgress;
    
    static final int DOWNLOAD_START=0;
    static final int DOWNLOADING=1;
    static final int DOWNLOAD_FINISH=2;
    
    Handler mMainHanlder,mWokrThreadHanler;//主线程和工作线程的Handler,分别处理消息。
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initMainHandler();
        setListener();//下载按钮的监听器
        createWorkThread();
    }

    private void createWorkThread() {
        new Thread(){//工作线程
            public void run() {//Looper和mWokrThreadHanler都是在工作线程创建
                Looper.prepare();//创建Looper对象和工作线程中的MessageQueue
                mWokrThreadHanler=new Handler(){
                    public void handleMessage(Message msg) {
                        if(msg.what==DOWNLOAD_START){
                            Log.i("main","work thread start downlad");
                            for(int i=1;i<=100;i++){
                                SystemClock.sleep(20);
                                Message msg2 = Message.obtain();
                                msg2.what=DOWNLOADING;
                                msg2.arg1=i;
                                mMainHanlder.sendMessage(msg2);//发送到主线程的消息队列,然后主线程的Looper从主线程消息队列取出来,调用mMainHanlder处理
                                mProgressBar.setProgress(i);
                            }
                            //循环结束后发送完成消息
                            Message msg2 = Message.obtain();
                            msg2.what=DOWNLOAD_FINISH;
                            mMainHanlder.sendMessage(msg2);//发送到主线程
                        }
                    };
                };
                Looper.loop();//轮询MessageQueue,取到消息后交给mWokrThreadHanler的handleMessage()方法进行处理(上面的方法),
            };
        }.start();
    }

    private void setListener() {
        findViewById(R.id.btnStartDownload).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //工作线程Handler向自己工作线程发送消息,发送至工作线程的消息队列MessageQueue中,空消息通知工作线程开始下载
                mWokrThreadHanler.sendEmptyMessage(DOWNLOAD_START);
            }
        });
    }

    private void initMainHandler() {
        mMainHanlder=new Handler(){//在主线程new,所以为主线程服务
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                case DOWNLOADING:
                    mtvProgress.setText(msg.arg1+"%");
                    break;
                case DOWNLOAD_FINISH:
                    Toast.makeText(MainActivity.this, "下载完成", 2000).show();
                    break;
                }
            }
        };
    }

    private void initView() {
        mProgressBar=(ProgressBar) findViewById(R.id.pb);
        mtvProgress=(TextView) findViewById(R.id.tvProgress);
    }
}

页面:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:orientation="vertical">

    <Button
        android:id="@+id/btnStartDownload"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开始下载" />
    <ProgressBar
        android:id="@+id/pb"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:max="100"/>
    <TextView 
        android:id="@+id/tvProgress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:text="0%"/>
</LinearLayout>

 

posted @ 2015-10-18 14:32  无天666  阅读(170)  评论(0编辑  收藏  举报