Android线程间通信
前言:内容主要从android线程间通信方式进行入手,首先分析了线程间通信的几种方式,再深入分析线程间通信的机制,主要分析工作线程与工作线程间通信,因为主线程和工作线程间通信网上已经很多例子了。
目录
一、Android线程间通信的四种实现方式
线程间通信方式主要有四种,分别是:Handler、runOnUiThread、View.post(Runnable r) 、AsyncTask
1.Handler进行线程通信==>消息机制
private void test() {
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 123:
tv.setText(""+msg.obj);
break;
}
}
};
new Thread(){
@Override
public void run() {
//TODO SOMETHING
}
Message message=new Message();
message.what=123;
message.obj="通过Handler机制";
handler.sendMessage(message);
}
}.run();
}
关于handler的具体知识可以看一下我写的安卓的消息机制,后面就不重复介绍了。只有一点需要注意:
Handler 对象在哪个线程下构建(Handler的构造函数在哪个线程下调用),那么Handler 就会持有这个线程的Looper引用和这个线程的消息队列的引用。因为持有这个线程的消息队列的引用,意味着这个Handler对象可以在任意其他线程给该线程的消息队列添加消息,也意味着Handler的handlerMessage 肯定也是在该线程执行的。
2.runOnUiThread
private void test(){
new Thread(){
@Override
public void run() {
//TODO SOMETHING
}
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText("通过runOnUiThread方法");
}
});
}
}.run();
}
3.View.post(Runnable r)
private void test(){
new Thread(){
@Override
public void run() {
//TODO SOMETHING
}
tv.post(new Runnable() {
@Override
public void run() {
tv.setText("通过View.post(Runnable r) 方法");
}
});
}
}.run();
}
4.AsyncTask
private void test(){
new MyAsyncTask().execute("通过AsyncTask方法");
}
private class MyAsyncTask extends AsyncTask{
@Override
protected Object doInBackground(Object[] objects) {
//TODO SOMETHING 耗时操作
}
return /*object*/;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
tv.setText(o.toString());
}
}
二、线程间通信机制
问题?在我们了解的线程间通信方式中,大多数都是主线程和工作线程间的通信,很少看到工作线程和工作线程之间的通信。所以关于主线程和工作线程的通信机制就不赘述了,网上相关文章已经很多了,对于我的疑惑,我想多了解一些关于工作与工作线程之间的通信。
首先来看一下安卓的消息机制的图吧,这是网上找的:
在消息机制中,已经说的很明白了,再赘述一下吧:
Handler 对象在哪个线程下构建(Handler的构造函数在哪个线程下调用),那么Handler 就会持有这个线程的Looper引用和这个线程的消息队列的引用。因为持有这个线程的消息队列的引用,意味着这个Handler对象可以在任意其他线程给该线程的消息队列添加消息,也意味着Handler的handlerMessage 肯定也是在该线程执行的。
所以要实现工作与工作线程之间的通信,和主线程和工作线程间的通信一样,唯一的区别就是要创建Looper,然后调用loop方法,因为主线程已经在ActivityThread中默认为我们创建好了,所以在主线程中我们可以直接使用。
例子:创建Thread-one和Thread-tow两个工作线程,实现通信:
注意:由于是子线程,所以都要创建Looper
package com.example.jnitest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Handler handler1,handler2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建两个子线程,下面来进行两个子线程之间的通信
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();//创建Looper
handler1 = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 2:
String str = (String) msg.obj;
System.out.println(Thread.currentThread()+":"+str);
Message message = new Message();
message.obj = "hello thread2";
message.what = 1;
handler2.sendMessage(message);
break;
}
}
};
Looper.loop();//开启消息循环
}
},"Thread-one").start();
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
handler2 = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 0:
Message message = new Message();
message.what = 2;
message.obj = "hello thread1";
handler1.sendMessage(message);
break;
case 1:
String str = (String) msg.obj;
System.out.println(Thread.currentThread()+":"+str);
break;
}
}
};
Looper.loop();
}
},"Thread-tow").start();
//为了保证获取到的handler不为null,所以进行睡眠
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(handler1+" :"+handler2);
Message message = new Message();
message.what = 0;
handler2.sendMessage(message);
}
}
输出结果:可以看到都有输出