首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android前台服务的使用(二)--使用LiveEventBus实现进程间通讯(附源码)

Android前台服务的使用(二)--使用LiveEventBus实现进程间通讯(附源码)

作者头像
Vaccae
发布2022-09-28 12:22:52
发布2022-09-28 12:22:52
2.3K00
代码可运行
举报
文章被收录于专栏:微卡智享微卡智享
运行总次数:0
代码可运行

学更好的别人,

做更好的自己。

——《微卡智享》

本文长度为2654,预计阅读6分钟

前言

上一篇《Android前台服务的使用(一)》介绍了Android前台服务的使用,其中通讯用的广播方式在来接消息,在文中最后也说过LiveEventBus实现了进程中的通讯,在《Android使用LiveEventBus消息实现组件间通讯》中有介绍过LiveEventBus的使用(不包括跨进程),本篇就来看看实现进程间的消息通讯。

实现效果

代码实现

微卡智享

01

加入LiveEventBus依赖项

在build.gradle(app)和(testsrc)中都加入LiveEventBus的依赖

代码语言:javascript
代码运行次数:0
运行
复制
dependencies {
    implementation 'io.github.jeremyliao:live-event-bus-x:1.8.0'
}

02

LiveEventBus的使用

在MyService中加入InitLiveEventBus的初始化,上图中可以看到这里使用的是observeforever模式,所以要注意两点:

  1. 单独定义observe方法,
  2. 需要手动释放才可以。

单独定义Observer

定义的Observer中可以看到,接收到的字符串信息后,我们前面加上了一个“服务端接收到的消息:”后再发送回去。重点就是postAcrossApp

代码语言:javascript
代码运行次数:0
运行
复制
            LiveEventBus.get<String>(MESSAGE_RET)
                .postAcrossApp(retstr)

原来介绍的发送消息一般只有post就可以了,而跨进程的消息通讯,必须使用postAcrossApp,否则是接收不到消息的。

手动释放

代码中我们也把上次开启广播的方式都已经注释掉了,完整的MyService代码:

代码语言:javascript
代码运行次数:0
运行
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档