Android多线程编程

(来自《第一行代码》)整理总结

JAVA中的多线程
1、 继承Thread

class MyThread extends Thread {
    @override
    public void run() {
    // 具体的处理逻辑
    }
}
new MyThread().start();

2、实现Runnable

class MyThread implements Runnable {
    @override
    public void run() {
    // 具体的处理逻辑
    }
}
MyThread myThread = new MyThread();
new Thread(myThread).start();

3、匿名类的方式(最常用)

new Thread(new Runnable() {
                @Override
                public void run() {
                    // 处理具体的逻辑
                }
            }).start();

一、使用Handler(处理者)在子线程中更新UI:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/change_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Change Text" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Hello world"
        android:textSize="20sp" />

</RelativeLayout>
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {

    public static final int UPDATE_TEXT = 1;// 表示更新TextView这个动作
    private TextView text;
    private Button changeText;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case UPDATE_TEXT:
                text.setText("Nice to meet you");
                break;
            default:
                break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView) findViewById(R.id.text);
        changeText = (Button) findViewById(R.id.change_text);
        changeText.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.change_text:
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Message message = new Message();
                    message.what = UPDATE_TEXT;
                    handler.sendMessage(message);
                }
            }).start();
            break;
        default:
            break;
        }
    }
}

机制:
1、Message是线程之间传递的消息,可以使用what字段,还可以使用arg1和arg2字段来携带一些整形数据,使用obj字段携带一个Object对象。
2、Handler主要用于发送和处理消息。发送消息一般是使用Handler的sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到Handler的handleMessage()。
3、MessageQueue是消息队列的消息,主要用于存放所有通过Handler发送的消息,这些消息一直存在于消息队列中,等待被处理。每个线程中只会有一个MessageQueue对象。
4、Looper是每个线程中的MessageQueue的管家。每个线程中也只会有一个Looper对象。负责将消息队列中的消息传递到Handler的handleMessage()的方法中。
过程:1、主线程创建Handler对象,重写handleMessage()方法;
2、在子线程中创建Message对象,然后发送;
3、消息被添加到消息队列中,Looper取出消息,分发到handleMessage()方法中安心地进行UI操作。

二、使用AsyncTask

/**
 * AsyncTask基本用法
 * 
 * @author Administrator
 *
 */
class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
    // 三个参数分别表示(Params)在执行AsyncTask时需要传入的参数;
    // (Progress)当前的进度;
    // (Result)任务处理执行完毕后返回的结果
    private ProgressDialog progressDialog;
    private String[] valus;
    private Context context;

    private int doDownload() {
        // TODO Auto-generated method stub
        return 0;
    }

    // 界面上的初始化操作,比如显示一个进度条对话框
    @Override
    protected void onPreExecute() {
        // 显示进度对话框
        progressDialog.show();
    }

    // 在子线程中运行,处理耗时的任务
    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            while (true) {
                // 这是一个虚构的方法
                int downloadPercent = doDownload();
                // 调用publishProgress(Progress...)反馈当前任务的执行进度
                publishProgress(downloadPercent);
                if (downloadPercent >= 100) {
                    break;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    // 在任务中调用publishProgress(Progress...)后,这个方法很快被调用,在这里可进行UI操作
    @Override
    protected void onProgressUpdate(Integer... values) {
        // 在这里更新下载进度
        progressDialog.setMessage("Downloaded " + valus[0] + "%");
    }

    // 后台任务执行完毕并通过return语句进行返回,这个方法被调用,可利用返回的数据进行UI操作(收尾工作)
    @Override
    protected void onPostExecute(Boolean result) {
        // 关闭进度对话框
        progressDialog.dismiss();
        // 提醒任务执行的结果
        if (result) {
            Toast.makeText(context, "Download succeeded", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(context, "Download failed", Toast.LENGTH_SHORT).show();
        }
    }

两者比较:
AsyncTask在代码上比Handler要轻量级,而实际上要比Handler更耗资源,因为AsyncTask底层是一个线程池,而Handler仅仅是发送了一个消息队列。
但是,如果异步任务的数据特别庞大,AsyncTask线程池的结构优势就体现出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值