You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin跨应用:如何从Service向Activity传递数据?

跨应用场景下Service向Activity传数据(Kotlin实现)

问题

要在跨应用场景下实现Service往Activity传递数据,已经用Messenger搞定了Activity到Service的通信,但找不到Kotlin版的Service到Activity实现方案,不清楚怎么把Activity的IncomingHandler和Service的onServiceConnected绑定起来调用mService?.send(msg)。

你当前尝试的LocalBroadcast代码

Service端代码

val intent = Intent("TO_SALE_APP")
intent.putExtra("RESPONSE_CODE", responseCode)
intent.putExtra("STATUS", status)
intent.putExtra("PAYMENT_TYPE", paymentType)
LocalBroadcastManager.getInstance(this.applicationContext).sendBroadcast(intent)

Activity端代码

private val mMessageReceiver: BroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent) {
        val responseCode = intent.getStringExtra("RESPONSE_CODE")
        val status = intent.getIntExtra("STATUS",0)
        val paymentType = intent.getIntExtra("PAYMENT_TYPE",0)
        Log.d("myTAG","data receive on activity!")
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    // 其他初始化代码
    LocalBroadcastManager.getInstance(this).registerReceiver(
        mMessageReceiver, IntentFilter("TO_SALE_APP")
    )
}

注意:LocalBroadcast跨应用无效

LocalBroadcastManager仅支持同应用内通信,跨应用场景下完全无法传递数据,所以这个方案走不通,必须改用Messenger或AIDL。下面直接给出Messenger实现跨应用双向通信的Kotlin完整代码:

Messenger跨应用双向通信(Kotlin版)

1. Service端代码

Service需要保存Activity传递过来的Messenger,后续用它向Activity回传消息:

class RemoteService : Service() {
    // 处理Activity发来的消息
    private val serviceMessenger = Messenger(object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                // 接收Activity请求,同时保存客户端的Messenger
                0 -> {
                    val clientMessenger = msg.replyTo
                    // 模拟Service处理完任务后,向Activity回传数据
                    val replyMsg = Message.obtain(null, 1)
                    val bundle = Bundle().apply {
                        putString("RESPONSE_CODE", "SUCCESS")
                        putInt("STATUS", 1)
                        putInt("PAYMENT_TYPE", 2)
                    }
                    replyMsg.data = bundle
                    // 发送消息给Activity
                    clientMessenger?.send(replyMsg)
                }
                else -> super.handleMessage(msg)
            }
        }
    })

    override fun onBind(intent: Intent): IBinder {
        return serviceMessenger.binder
    }
}

别忘了在Manifest中注册Service,必须开启android:exported="true"允许跨应用绑定:

<service
    android:name=".RemoteService"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.REMOTE_SERVICE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

2. Activity端代码

Activity需要自定义IncomingHandler接收Service的回传消息,绑定Service时把自己的Messenger传给Service:

class MainActivity : AppCompatActivity() {
    // 接收Service回传消息的Messenger
    private val clientMessenger = Messenger(object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                // 处理Service回传的数据
                1 -> {
                    val responseCode = msg.data.getString("RESPONSE_CODE")
                    val status = msg.data.getInt("STATUS", 0)
                    val paymentType = msg.data.getInt("PAYMENT_TYPE", 0)
                    Log.d("myTAG", "收到Service数据:responseCode=$responseCode, status=$status, paymentType=$paymentType")
                }
                else -> super.handleMessage(msg)
            }
        }
    })

    private var serviceMessenger: Messenger? = null
    private val serviceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            // 绑定成功,获取Service的Messenger用于发消息
            serviceMessenger = Messenger(service)
            // 向Service发送消息,并附带自己的Messenger让Service能回传
            val msg = Message.obtain(null, 0)
            msg.replyTo = clientMessenger
            serviceMessenger?.send(msg)
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            serviceMessenger = null
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 绑定跨应用的Service
        val intent = Intent("com.example.REMOTE_SERVICE")
        // 跨应用必须指定目标应用包名(替换为Service所在APP的包名)
        intent.setPackage("com.example.remoteapp")
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 解绑Service
        unbindService(serviceConnection)
    }
}

重点提醒

  • 跨应用绑定时,必须指定目标Service所在APP的包名,否则系统无法找到对应Service
  • Service必须设置android:exported="true",并通过intent-filter暴露可调用的action
  • Messenger基于Handler实现,所有消息处理都在主线程,适合轻量级跨进程通信;复杂场景建议使用AIDL

内容的提问来源于stack exchange,提问作者Sezai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 06:10:37