一、线程的基本用法
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