Android线程间通信
前言:内容主要从android线程间通信方式进行入手,首先分析了线程间通信的几种方式,再深入分析线程间通信的机制,主要分析工作线程与工作线程间通信,因为主线程和工作线程间通信网上已经很多例子了。
目录
Android线程间通信
一、Android线程间通信的四种实现方式
1.Handler进行线程通信==>消息机制
2.runOnUiThread
3.View.post(Runnable r)
4.AsyncTask
二、线程间通信机制
一、Android线程间通信的四种实现方式
线程间通信方式主要有四种,分别是:Handler、runOnUiThread、View.post(Runnable r) 、AsyncTask
1.Handler进行线程通信==>消息机制
private void test() {Handler handler=new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case 123:tv.setText(""+msg.obj);break;}}};new Thread(){@Overridepublic 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(){@Overridepublic void run() {//TODO SOMETHING}runOnUiThread(new Runnable() {@Overridepublic void run() {tv.setText("通过runOnUiThread方法");}});}}.run();}
3.View.post(Runnable r)
private void test(){new Thread(){@Overridepublic void run() {//TODO SOMETHING}tv.post(new Runnable() {@Overridepublic void run() {tv.setText("通过View.post(Runnable r) 方法");}});}}.run();}
4.AsyncTask
private void test(){new MyAsyncTask().execute("通过AsyncTask方法");}private class MyAsyncTask extends AsyncTask{@Overrideprotected Object doInBackground(Object[] objects) {//TODO SOMETHING 耗时操作}return /*object*/;}@Overrideprotected 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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//创建两个子线程,下面来进行两个子线程之间的通信new Thread(new Runnable() {@Overridepublic void run() {Looper.prepare();//创建Looperhandler1 = new Handler(){@Overridepublic 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() {@Overridepublic void run() {Looper.prepare();handler2 = new Handler(){@Overridepublic 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);}}
输出结果:可以看到都有输出