学更好的别人,
做更好的自己。
——《微卡智享》
本文长度为2654字,预计阅读6分钟
前言
上一篇《Android前台服务的使用(一)》介绍了Android前台服务的使用,其中通讯用的广播方式在来接消息,在文中最后也说过LiveEventBus实现了进程中的通讯,在《Android使用LiveEventBus消息实现组件间通讯》中有介绍过LiveEventBus的使用(不包括跨进程),本篇就来看看实现进程间的消息通讯。
实现效果
代码实现
微卡智享
01
加入LiveEventBus依赖项
在build.gradle(app)和(testsrc)中都加入LiveEventBus的依赖
dependencies {
implementation 'io.github.jeremyliao:live-event-bus-x:1.8.0'
}
02
LiveEventBus的使用
在MyService中加入InitLiveEventBus的初始化,上图中可以看到这里使用的是observeforever模式,所以要注意两点:
单独定义observe方法,
需要手动释放才可以。
单独定义Observer
定义的Observer中可以看到,接收到的字符串信息后,我们前面加上了一个“服务端接收到的消息:”后再发送回去。重点就是postAcrossApp
LiveEventBus.get<String>(MESSAGE_RET)
.postAcrossApp(retstr)
原来介绍的发送消息一般只有post就可以了,而跨进程的消息通讯,必须使用postAcrossApp,否则是接收不到消息的。
手动释放
代码中我们也把上次开启广播的方式都已经注释掉了,完整的MyService代码:
package pers.vaccae.servicedemo
import android.app.*
import android.content.Intent
import android.os.IBinder
import android.util.Log
import androidx.lifecycle.Observer
import com.jeremyliao.liveeventbus.LiveEventBus
const val TAG = "MyService"
const val MESSAGE_ACTION = "MESSAGE_ACTION"
const val MESSAGE_ID = "MESSAGE_ID"
const val MESSAGE_TYPE = "MESSAGE_TYPE"
const val MESSAGE_RET = "MESSAGE_RET"
class MyService : Service() {
private lateinit var mMsgRecv: MessageReceiver
private val observer = Observer<String>{
try {
showNotification(it)
val retstr = "服务端接收到消息:${it}"
LiveEventBus.get<String>(MESSAGE_RET)
.postAcrossApp(retstr)
}
catch (e:Exception){
showNotification(e.message.toString())
}
}
override fun onCreate() {
super.onCreate()
Log.d(TAG, "service onCreate()")
//注册广播
// mMsgRecv = MessageReceiver()
// val mFilter = IntentFilter()
// mFilter.addAction(MESSAGE_ACTION)
// registerReceiver(mMsgRecv, mFilter)
InitLiveEventBus()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "service onStartCommand()")
NotificationUtil.getInstance(this, MainActivity::class.java, packageName)
val notification = NotificationUtil.mNotifiCationBuilder
.setContentTitle("前台服务测试")
.setContentText("我是一个前台服务的Demo")
.setWhen(System.currentTimeMillis())
.setSmallIcon(androidx.loader.R.drawable.notification_bg)
.setContentIntent(NotificationUtil.mPendingIntent)
.build()
// 开始前台服务
startForeground(110, notification)
NotificationUtil.mNotificationManager.notify(1, notification)
return super.onStartCommand(intent, flags, startId)
}
override fun onBind(intent: Intent): IBinder {
Log.d(TAG, "service onBind()")
TODO("Return the communication channel to the service.")
}
override fun onDestroy() {
Log.d(TAG, "service onDestroy")
//停止前台服务
stopForeground(true)
//终止广播
//unregisterReceiver(mMsgRecv)
LiveEventBus
.get<String>(MESSAGE_TYPE)
.removeObserver(observer)
super.onDestroy()
}
/**
* 初始化LiveEventBus
* 1、配置LifecycleObserver(如Activity)接收消息的模式(默认值true):
* true:整个生命周期(从onCreate到onDestroy)都可以实时收到消息
* false:激活状态(Started)可以实时收到消息,非激活状态(Stoped)无法实时收到消息,需等到Activity重新变成激活状
* 态,方可收到消息
* 2、autoClear
* 配置在没有Observer关联的时候是否自动清除LiveEvent以释放内存(默认值false)
* */
fun InitLiveEventBus(){
LiveEventBus.config()
.lifecycleObserverAlwaysActive(true)
.autoClear(false)
LiveEventBus.get<String>(MESSAGE_TYPE)
.observeForever(observer)
}
fun showNotification(msg:String,title:String="前台服务监听"){
Log.d(TAG, msg)
val notification = NotificationUtil.mNotifiCationBuilder
.setContentTitle(title)
.setContentText(msg)
.setWhen(System.currentTimeMillis())
.setSmallIcon(androidx.loader.R.drawable.notification_bg)
.setContentIntent(NotificationUtil.mPendingIntent)
.setSound(null)
.build()
NotificationUtil.mNotificationManager.notify(1, notification)
}
}
03
MainActivity中调用
MainActivity中的订阅可以看到,observe是用的普通模式,所以无需要再进行手动释放了,会根据生命周期自己释放,而当前的MainActivity中因为和MyService在一个项目中,所以这里直接用post发送消息也一样能接收到。
而在testsrv项目的MainActivity中,我们的发送就改为postAcrossApp了,这样才能实现跨进程的通讯。
这样使用LiveEventBus加上前台服务就实现的我们最初想到的业务的硬件控制的解耦,并且用LiveEventBus后不需要使用广播的方式两边写好多的代码。
源码地址
https://github.com/Vaccae/AndroidServicewithLiveEventBus
点击阅读原文可以看到“码云”的代码地址
完
往期精彩回顾
Android Kotlin使用ARouter组件化路由及DataStore替代SharedPreferences保存数据