前言:很多人写项目都会用到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()}
运行结果:主线程发布->新的子线程接收(理解成子线程接收也可以)