Android 多线程编程

一、线程的基本用法

1.1 使用Thread类
class MyThread extends Thread{
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			//执行耗时任务
		}
	}
MyThread myThread=new MyThread();
myThread.start();

1.2 使用Runnable接口
 class MyThread2 implements Runnable{

		@Override
		public void run() {
			// TODO Auto-generated method stub
			//执行耗时操作
		}
		
	}
new Thread(new MyThread2()).start();

1.3 使用匿名方式。(用的比较多)
new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//执行耗时任务
			}
		}).start();

1.4 使用java.util.concurrent中的Executors
ExecutorService executorService=Executors.newFixedThreadPool(3);
		executorService.execute(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//执行耗时任务
			}
		});


二、异步消息处理机制

安卓中有个特性是不能再主线程(UI线程)处理耗时操作,比如不能在主线程中发网络请求操作,所以提供了Handler的异步消息处理机制。

package com.example.androidmthread;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends Activity {

	private TextView mTvName;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mTvName = (TextView) findViewById(R.id.tv_name);
	}

	Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			// 接受处理消息,进而更新Ui
			if (msg.what == success_flag) {
				String data = (String) msg.obj;
				mTvName.setText(data);
			} else if (msg.what == fail_flag) {

			}

		};
	};

	private static final int success_flag = 1;
	private static final int fail_flag = 2;

	private void updateData() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Message message = Message.obtain();
				String data = "zzzz";// 执行耗时业务操作获取数据
				if (!TextUtils.isEmpty(data)) {
					message.what = success_flag;
					message.obj = data;
				} else {
					message.what = fail_flag;
				}
				// 发送消息
				mHandler.sendMessage(message);
			}
		}).start();
	}

}
2.1  Message

message是用于线程之间数据通信的中间传输类,包括what,obj等属性用于数据的赋值传输。

2.1 Handler

hander是处理器的意思,主要用于消息的发送sendMessage和消息的处理handleMessage。

2.1 MessageQueue

MessageQueue是消息队列的意思,既然是属于队列结构,即遵循“先进先出”的模式,它用于表示

所有通过hander发送的消息,是一个消息队列集合;每一个线程都会有一个自己的MessageQueue对象。

2.1 Looper
消息循环Looper 是每个线程中的 MessageQueue 的管家,调用 Looper 的 **loop() **方法后,就会进入到一个无限循环当中,然后每当发现 MessageQueue 中存在一条消息,就会将它取出,并传递到 Handler 的 handleMessage() 方法中。每个线程中 都会有一个 Looper 对象。


注意:在安卓中子线程和UI线程通信,后台默认有个消息队列,不需要程序员创建维护;如果子线程和子线程通信那么需要程序员创建好线程的消息队列,主要用到Looper.prepare();和Looper.loop();即可,代码如下
package com.example.androidmthread;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

public class Thread01 implements Runnable {

	public static Handler mHandler;

	@Override
	public void run() {
		// TODO Auto-generated method stub
		// 启动一个消息队列循环
		Looper.prepare();
		mHandler = new Handler() {

			public void handleMessage(android.os.Message msg) {
				String data = (String) msg.obj;
				Log.d("Thread01", data);
			};
		};
		
		//发送消息
		Message msg = Message.obtain();
		msg.obj = "Thread01-msg";
		if (Thread02.mHandler != null) {
			Thread02.mHandler.sendMessage(msg);
		}
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
		Looper.loop();

		

	}

}

//Thread02.java
package com.example.androidmthread;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

public class Thread02 implements Runnable {

	public static Handler mHandler;

	@Override
	public void run() {
		// TODO Auto-generated method stub
		// 启动一个消息队列循环
		Looper.prepare();
		mHandler = new Handler() {

			public void handleMessage(android.os.Message msg) {
				String data = (String) msg.obj;
				Log.d("Thread02", data);
			};
		};
		
		
		//发送消息
		Message msg = Message.obtain();
		msg.obj = "Thread02-msg";
		if (Thread01.mHandler != null) {
			Thread01.mHandler.sendMessage(msg);
		}
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
		Looper.loop();

	}

}

三、使用 AsyncTask

 AsyncTask是安卓内置封装好用于异步操作的类,简化一般异步操作过程,主要实现过程是通过继承AsyncTask抽象类,然后重写onPreExecute(主要执行预处理操作,运行在UI线程)、onPostExecute(主要执行收尾工作,运行在UI线程)、onProgressUpdate(主要负责更新UI执行进度情况,每调用一次publishProgress方法便会执行一次该回调,运行在UI线程)、doInBackground(主要负责执行耗时的操作,运行在子线程中),通过这些方法便可以轻松实现线程之间的异步操作。

package com.example.androidmthread;

import android.database.CursorJoiner.Result;
import android.os.AsyncTask;
import android.widget.Toast;

/**
 * 下载任务
 * 
 * @author zgq
 *
 */
public class DownloadTask extends AsyncTask<String, Integer, Boolean> {

	@Override
	protected void onPreExecute() {
		// TODO Auto-generated method stub
		super.onPreExecute();
		// 用于预处理
		// progressDialog.show(); // 显示进度对话框
	}

	@Override
	protected void onPostExecute(Boolean result) {
		// TODO Auto-generated method stub
		super.onPostExecute(result);
		// 执行完耗时任务后的收尾工作,通常执行更新UI工作
		// progressDialog.dismiss(); // 关闭进度对话框
		// 在这里提示下载结果
		if (result) {
			// 成功
		} else {
			// 失败
		}

	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		// TODO Auto-generated method stub
		super.onProgressUpdate(values);
		// 用于执行更新执行进度
		// 在这里更新下载进度
		// progressDialog.setMessage("Downloaded " + values[0] + "%");

	}

	@Override
	protected Boolean doInBackground(String... params) {
		// TODO Auto-generated method stub
		// 执行耗时任务
		try {
			String url = params[0];
			while (true) {
				int downloadPercent = doDownload(url); // 这是一个虚构的方法
				publishProgress(downloadPercent);
				if (downloadPercent >= 100) {
					break;
				}
			}

		} catch (Exception e) {
			return false;
		}

		return true;
	}

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

}
//执行调用
DownloadTask downloadTask=new DownloadTask();
String url="";
downloadTask.execute(url);
思路来源: https://www.jianshu.com/p/9e414e734b74

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值