当前位置: 代码迷 >> 综合 >> Kotlin-Android开发之透彻理解EventBus的MAIN、POSTING、BACKGROUND、ASYNC,4种线程模式
  详细解决方案

Kotlin-Android开发之透彻理解EventBus的MAIN、POSTING、BACKGROUND、ASYNC,4种线程模式

热度:98   发布时间:2024-01-25 08:17:40.0

前言:很多人写项目都会用到EventBus,可以说解决了很多麻烦的事情,区区几行代码,就能解决四大组件的通信,异步线程和主线程之间的通信。这次主要介绍EventBus的4种线程模式:ThreadMode.MAIN(常用)、ThreadMode.POSTING、ThreadMode.BACKGROUND、ThreadMode.ASYNC


EventBus的简单用法

1.添加eventbus3.1.1依赖

implementation 'org.greenrobot:eventbus:3.1.1'

2.在MainActivy中接收SecondActivity中EventBus发送的信息(注意:在onCreate()里面注册,在onDestory()中注销)

class MainActivity : AppCompatActivity() {private lateinit var button: Buttonoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)EventBus.getDefault().register(this)  //注册EventBusbutton = findViewById(R.id.btn1)button.setOnClickListener{var intent:Intent = Intent(this,SecondActivity::class.java )startActivity(intent)}}/*** 事件响应方法* 接收消息*/@Subscribe(threadMode = ThreadMode.MAIN)fun onGetMessage1(string: String) {Log.e("--ThreadMode.MAIN-",string)}override fun onDestroy() {super.onDestroy()EventBus.getDefault().unregister(this)//注销}
}

3.在SecondActivity中发送消息,SecondActivity代码

class SecondActivity :AppCompatActivity() {private lateinit var btn:Buttonoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_second)btn = findViewById(R.id.btn2)btn.setOnClickListener {EventBus.getDefault().post("Hello");//发送消息finish()//结束当前页面}}
}

4.运行结果:


(一)ThreadMode.MAIN(常用)线程模式:表示无论事件是在UI线程(主线程)或者子线程发布出来的,该事件订阅方法onEvent都会在UI线程中执行。就是子线程发布->主线程接收,主线程发布->主线程接收。

请看Demo1:分别在MainActivity和SecondActivity中的onCreate()和以及在订阅事件中打印当前的线程的ID

class MainActivity : AppCompatActivity() {private lateinit var button: Buttonoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)EventBus.getDefault().register(this)button = findViewById(R.id.btn1)button.setOnClickListener{var intent:Intent = Intent(this,SecondActivity::class.java )startActivity(intent)}var tid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--MainActivity-",tid.toString())}/*** 事件响应方法* 接收消息*/@Subscribe(threadMode = ThreadMode.MAIN)fun onGetMessage1(string: String) {var tid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--ThreadMode.MAIN-",tid.toString())Log.e("--ThreadMode.MAIN-",string)}override fun onDestroy() {super.onDestroy()EventBus.getDefault().unregister(this)}
}
class SecondActivity :AppCompatActivity() {private lateinit var btn:Buttonoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_second)btn = findViewById(R.id.btn2)var tid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivity-",tid.toString())btn.setOnClickListener {var btntid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivityBtn-",btntid.toString())EventBus.getDefault().post("Hello");finish()}}
}

运行结果:主线程发布->主线程接收

Demo2:把SecondActivity中的event发布事件运行到子线程中,修改SecondActivity的代码

     btn.setOnClickListener {Thread(Runnable {EventBus.getDefault().post("Hello");var btntid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivityBtn-",btntid.toString())}).start()finish()}

运行结果:子线程发布->主线程接收


(二)ThreadMode.POSTING线程模式:表示事件在哪个线程中发布出来的,事件订阅函数onEvent就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。就是子线程发布->子线程接收,主线程发布->主线程接收。

Demo1:

class MainActivity : AppCompatActivity() {private lateinit var button: Buttonoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)EventBus.getDefault().register(this)var tid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--MainActivity-",tid.toString())button = findViewById(R.id.btn1)button.setOnClickListener{var intent:Intent = Intent(this,SecondActivity::class.java )startActivity(intent)}}/*** 事件响应方法* 接收消息*/@Subscribe(threadMode = ThreadMode.POSTING)fun onGetMessage2(string: String) {var tid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--ThreadMode.POSTING-",tid.toString())Log.e("--ThreadMode.POSTING-",string)}override fun onDestroy() {super.onDestroy()EventBus.getDefault().unregister(this)}
}
class SecondActivity :AppCompatActivity() {private lateinit var btn:Buttonoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_second)btn = findViewById(R.id.btn2)var tid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivity-",tid.toString())btn.setOnClickListener {Thread(Runnable {EventBus.getDefault().post("Hello");var btntid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivityBtn-",btntid.toString())}).start()finish()}}
}

运行结果:子线程发布->子线程接收

Demo2:修改SecondActivity中的发布事件在主线程中

 btn.setOnClickListener {EventBus.getDefault().post("Hello");var btntid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivityBtn-",btntid.toString())finish()}

运行结果:主线程发布->主线程接收


(三)ThreadMode.BACKGROUND线程模式:表示如果事件在UI线程中发布出来的,那么订阅函数onEvent就会在子线程中运行,如果事件本来就是在子线程中发布出来的,那么订阅函数直接在该子线程中执行。也就是说主线程发布->子线程接收、子线程发布->子线程接收

Demo1:更改MainActivity中接收事件

    @Subscribe(threadMode = ThreadMode.BACKGROUND)fun onGetMessage3(string: String) {var tid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--ThreadMode.BACKGROUND",tid.toString())Log.e("--ThreadMode.BACKGROUND",string)}

SecondActivity中的发送事件

 btn.setOnClickListener {EventBus.getDefault().post("Hello");var btntid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivityBtn-",btntid.toString())finish()}

运行结果:主线程发布->子线程接收

Demo2:更改SecondActivity中的发布事件,运行在子线程中

        btn.setOnClickListener {Thread(Runnable {EventBus.getDefault().post("Hello");var btntid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivityBtn-",btntid.toString())}).start()finish()}

运行结果:子线程发布->子线程接收


(四)ThreadMode.ASYNC线程模式:使用这个模式的订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程来执行订阅函数。也就是说主线程发布->创建新的子线程接收、子线程发布->创建新的子线程接收(两个子线程不同)。

Demo1:更改MainActivy中的接收事件

    @Subscribe(threadMode = ThreadMode.ASYNC)fun onGetMessage4(string: String) {var tid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--ThreadMode.ASYNC",tid.toString())Log.e("--ThreadMode.ASYNC",string)}

更改SecondActivity中的发布事件

        btn.setOnClickListener {Thread(Runnable {EventBus.getDefault().post("Hello");var btntid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivityBtn-",btntid.toString())}).start()finish()}

运行结果:子线程发布->开启一个新的子线程接收

Demo2:更改SecondActivity中的发布事件

        btn.setOnClickListener {EventBus.getDefault().post("Hello");var btntid:Int = android.os.Process.myTid()//获取当前的线程Log.e("--SecondActivityBtn-",btntid.toString())finish()}

运行结果:主线程发布->新的子线程接收(理解成子线程接收也可以)

  相关解决方案