android线程间通信的四种实现方式
- 通过Handler机制
子线程与子线程之间通信
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();
thread1.start();
Handler handler = null;
while (handler == null) {
handler = thread1.getHandler();
}
thread2.setHandler(handler);
thread2.start();
}
class Thread1 extends Thread {
private Handler handler1;
public Handler getHandler() {//注意哦,在run执行之前,返回的是null
return handler1;
}
@Override
public void run() {
Looper.prepare();
handler1 = new Handler() {
public void handleMessage(android.os.Message msg) {
//这里处理消息
Log.i("MThread", "收到消息了:" + Thread.currentThread().getName() + "----" + msg.obj);
}
;
};
Looper.loop();
}
}
class Thread2 extends Thread {
private Handler handler1;
public void setHandler(Handler handler) {//注意哦,在run执行之前,返回的是null
handler1 = handler;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
Message msg = Message.obtain();
msg.what = 1;
msg.obj = System.currentTimeMillis() + "";
handler1.sendMessage(msg);
Log.i("MThread", Thread.currentThread().getName() + "----发送了消息!" + msg.obj);
SystemClock.sleep(1000);
}
}
}
- unOnUiThread方法
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
- View.post(Runnable r)
tv.post(new Runnable() {
@Override
public void run() {
}
});
- AsyncTask
/**
* 步骤1:创建AsyncTask子类
* 注:
* a. 继承AsyncTask类
* b. 为3个泛型参数指定类型;若不使用,可用java.lang.Void类型代替
* c. 根据需求,在AsyncTask子类内实现核心方法
*/
private class MyTask extends AsyncTask<Params, Progress, Result> {
....
// 方法1:onPreExecute()
// 作用:执行 线程任务前的操作
// 注:根据需求复写
@Override
protected void onPreExecute() {
...
}
// 方法2:doInBackground()
// 作用:接收输入参数、执行任务中的耗时操作、返回 线程任务执行的结果
// 注:必须复写,从而自定义线程任务
@Override
protected String doInBackground(String... params) {
...// 自定义的线程任务
// 可调用publishProgress()显示进度, 之后将执行onProgressUpdate()
publishProgress(count);
}
// 方法3:onProgressUpdate()
// 作用:在主线程 显示线程任务执行的进度
// 注:根据需求复写
@Override
protected void onProgressUpdate(Integer... progresses) {
...
}
// 方法4:onPostExecute()
// 作用:接收线程任务执行结果、将执行结果显示到UI组件
// 注:必须复写,从而自定义UI操作
@Override
protected void onPostExecute(String result) {
...// UI操作
}
// 方法5:onCancelled()
// 作用:将异步任务设置为:取消状态
@Override
protected void onCancelled() {
...
}
}
/**
* 步骤2:创建AsyncTask子类的实例对象(即 任务实例)
* 注:AsyncTask子类的实例必须在UI线程中创建
*/
MyTask mTask = new MyTask();
/**
* 步骤3:手动调用execute(Params... params) 从而执行异步线程任务
* 注:
* a. 必须在UI线程中调用
* b. 同一个AsyncTask实例对象只能执行1次,若执行第2次将会抛出异常
* c. 执行任务中,系统会自动调用AsyncTask的一系列方法:onPreExecute() 、doInBackground()、onProgressUpdate() 、onPostExecute()
* d. 不能手动调用上述方法
*/
mTask.execute();
线程加锁通信的问题
线程间的通信其实是非常复杂的,这里是一个经典的线程加锁通信的问题。A, B, C三个打印机,每个打印机是一个线程,现在要求写一个程序,让A,B,C轮流打印自己的名字,每个打四次。
public class Printer extends Thread {
private String msg;
private Printer next;
public Printer(String msg) {
this.msg = msg;
}
@Override
public void run() {
for (int i = 1; i < 5; i++) {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第" + i + "次:" + this.msg);
synchronized (this.next) {
this.next.notify();
}
}
}
}
public static void main(String[] args) {
Printer A = new Printer("A");
Printer B = new Printer("B");
Printer C = new Printer("C");
A.next = B;
B.next = C;
C.next = A;
A.start();
B.start();
C.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (A) {
A.notify();
}
}
}
网友评论