觀察者模式是軟體設計模式的一種,分為被觀察者和觀察者。
當被觀察者的狀態發生變化,觀察者就會獲得事件通知並作出處理。
詳細介紹可以參考維基百科。
EventBus介紹
EventBus是一個針對Android最佳化的事件發送&訂閱框架,目的是為了簡化各個元件間的通訊。
EventBus主要是由事件、事件訂閱者、事件發布者構成:
- 事件是指任何要被發送的資料,可以是任意資料型別
- 事件訂閱者是指接收資料的目標元件
- 事件發布者是指負責發送資料的元件
EventBus有四種執行緒模式,具體如下:
- MAIN:事件處理會在主執行緒中執行,如果處理的時間過長,會引起ANR。
- POSTING:預設的處理模式,表示發送跟接收在同一個執行緒中執行。
- BACKGROUND:在這個模式下,如果事件是在主執行緒發送,那麼接收者就會建立一個執行緒處理事件。如果事件是在子執行緒發送,那接收者就會在發布者所在的執行緒中處理事件。注意:這個模式下無法進行UI相關的操作!
- ASYNC:不管事件從哪個執行緒發布,接收端都會在子執行緒處理。注意:這個模式下無法進行UI相關的操作!
用法
這裡使用一個Service作為發送者、一個Activity作為接收者。
Service每一秒發送一個數值+1的事件。當Activity接收到事件後,透過TextView顯示事件的數值,步驟如下:
1.首先在build.gradle加入EventBus套件庫,如下所示:
dependencies {
implementation 'org.greenrobot:eventbus:3.0.0'
}
2.宣告一個自訂類別,當作EventBus傳遞的參數,如下所示:
data class MyEvent(
var counter: Int? = null
)
3.建立Service,啟動方式這裡用Bind Service,如下所示:
class MyService : Service() {
private val mLocalBinder = LocalBinder()
private var counter = 0
private val handler = Handler()
private val timerCounter = object : Runnable {
override fun run() {
counter++
// 發送事件
EventBus.getDefault().post(
MyEvent(counter)
)
handler.postDelayed(this, 1000)
}
}
override fun onBind(arg0: Intent?): IBinder {
return mLocalBinder
}
override fun onCreate() {
super.onCreate()
handler.post(timerCounter)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return super.onStartCommand(intent, flags, startId)
}
override fun onUnbind(intent: Intent?): Boolean {
return super.onUnbind(intent)
}
override fun onDestroy() {
super.onDestroy()
handler.removeCallbacks(timerCounter)
}
inner class LocalBinder : Binder() {
val service: MyService = this@MyService
}
}
4.在Activity實作處理事件的function,並加入啟動Service的程式碼,如下所示:
class MainActivity : AppCompatActivity() {
private var mService: MyService? = null
private val mServiceConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, serviceBinder: IBinder) {
mService = (serviceBinder as LocalBinder).service
}
override fun onServiceDisconnected(name: ComponentName) {}
}
private val eventBus: EventBus by lazy {
EventBus.getDefault()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mService = null
val it = Intent(this, MyService::class.java)
bindService(it, mServiceConnection, BIND_AUTO_CREATE) //綁定Service
}
override fun onResume() {
super.onResume()
eventBus.register(this)
}
override fun onPause() {
super.onPause()
eventBus.unregister(this)
}
override fun onDestroy() {
super.onDestroy()
mService = null
unbindService(mServiceConnection)
}
// 訂閱事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEvent(event: MyEvent) {
textView.text = "count: ${event.counter}"
}
}
最後執行應用程式,即可看到TextView上的數值每秒+1。