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

如何从Service向Activity传递数据?求替代废弃LocalBroadcastManager的示例

Service 向 Activity 传递数据的几种实现方案

方案一:使用 LiveData(推荐)

LiveData 是 Jetpack 组件的一部分,自带生命周期感知能力,能自动适配 Activity 生命周期变化,避免内存泄漏,是当前最推荐的实现方式。

实现代码

  1. 定义共享的 ViewModel(用于持有可观察数据)
class DataSharedViewModel(application: Application) : AndroidViewModel(application) {
    // 可观察的数据容器,支持跨组件共享
    val dataLiveData = MutableLiveData<String>()

    // 提供更新数据的方法,子线程中用 postValue 确保线程安全
    fun updateData(data: String) {
        dataLiveData.postValue(data)
    }
}
  1. Service 端代码
class MyService : Service() {
    private lateinit var sharedViewModel: DataSharedViewModel

    override fun onCreate() {
        super.onCreate()
        // 通过 Application 获取全局共享的 ViewModel 实例
        sharedViewModel = ViewModelProvider(
            this,
            ViewModelProvider.AndroidViewModelFactory.getInstance(application)
        )[DataSharedViewModel::class.java]

        // 模拟后台线程持续生成并发送数据
        Thread {
            repeat(10) { count ->
                Thread.sleep(1000)
                sharedViewModel.updateData("Service 发送的第 ${count+1} 条数据")
            }
        }.start()
    }

    override fun onBind(intent: Intent): IBinder? = null
}
  1. Activity 端代码
class MainActivity : AppCompatActivity() {
    private lateinit var sharedViewModel: DataSharedViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 获取与 Service 同一实例的 ViewModel
        sharedViewModel = ViewModelProvider(
            this,
            ViewModelProvider.AndroidViewModelFactory.getInstance(application)
        )[DataSharedViewModel::class.java]

        // 观察数据变化,自动在主线程回调更新 UI
        sharedViewModel.dataLiveData.observe(this) { data ->
            findViewById<TextView>(R.id.tv_data).text = data
        }

        // 启动 Service
        startService(Intent(this, MyService::class.java))
    }
}

方案二:使用接口回调

适合需要实时交互的场景,需通过弱引用避免内存泄漏。

实现代码

  1. 定义回调接口
interface ServiceDataCallback {
    fun onDataReceived(data: String)
}
  1. Service 端代码
class MyService : Service() {
    // 用弱引用存储回调,防止 Activity 销毁后内存泄漏
    private val callbacks = mutableListOf<WeakReference<ServiceDataCallback>>()

    // 注册回调
    fun registerCallback(callback: ServiceDataCallback) {
        callbacks.add(WeakReference(callback))
    }

    // 移除回调
    fun unregisterCallback(callback: ServiceDataCallback) {
        callbacks.removeAll { it.get() == callback }
    }

    override fun onCreate() {
        super.onCreate()
        Thread {
            repeat(10) { count ->
                Thread.sleep(1000)
                val data = "Service 发送的第 ${count+1} 条数据"
                // 遍历回调列表,发送数据
                callbacks.forEach { ref ->
                    ref.get()?.onDataReceived(data)
                }
            }
        }.start()
    }

    // 通过 Binder 让 Activity 获取 Service 实例
    inner class MyBinder : Binder() {
        fun getService(): MyService = this@MyService
    }

    override fun onBind(intent: Intent): IBinder = MyBinder()
}
  1. Activity 端代码
class MainActivity : AppCompatActivity(), ServiceDataCallback {
    private var myService: MyService? = null
    private var isServiceBound = false

    private val serviceConnection = object : ServiceConnection {
        override fun onServiceConnected(className: ComponentName, service: IBinder) {
            val binder = service as MyService.MyBinder
            myService = binder.getService()
            myService?.registerCallback(this@MainActivity)
            isServiceBound = true
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            isServiceBound = false
            myService?.unregisterCallback(this@MainActivity)
            myService = null
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 绑定 Service
        bindService(Intent(this, MyService::class.java), serviceConnection, Context.BIND_AUTO_CREATE)
    }

    override fun onDataReceived(data: String) {
        // 切换到主线程更新 UI
        runOnUiThread {
            findViewById<TextView>(R.id.tv_data).text = data
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // 解绑时移除回调,避免内存泄漏
        if (isServiceBound) {
            myService?.unregisterCallback(this)
            unbindService(serviceConnection)
        }
    }
}

方案三:使用 Messenger

适合跨进程通信场景(同进程也适用),通过 Handler 传递 Message 实现数据交互。

实现代码

  1. Service 端代码
class MyService : Service() {
    // Service 端的 Handler,处理来自 Activity 的消息
    private val serviceHandler = Handler(Looper.getMainLooper()) { msg ->
        // 获取 Activity 的 Messenger,用于回复数据
        val activityMessenger = msg.replyTo
        // 模拟后台发送数据
        Thread {
            repeat(10) { count ->
                Thread.sleep(1000)
                val dataMsg = Message.obtain().apply {
                    what = 1 // 消息标识,用于区分不同类型消息
                    obj = "Service 发送的第 ${count+1} 条数据"
                }
                try {
                    activityMessenger?.send(dataMsg)
                } catch (e: RemoteException) {
                    e.printStackTrace()
                }
            }
        }.start()
        true
    }

    private val messenger = Messenger(serviceHandler)

    override fun onBind(intent: Intent): IBinder = messenger.binder
}
  1. Activity 端代码
class MainActivity : AppCompatActivity() {
    private var serviceMessenger: Messenger? = null
    private var isServiceBound = false

    // Activity 端的 Handler,处理来自 Service 的消息
    private val activityMessenger = Messenger(object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                1 -> {
                    val data = msg.obj as String
                    findViewById<TextView>(R.id.tv_data).text = data
                }
                else -> super.handleMessage(msg)
            }
        }
    })

    private val serviceConnection = object : ServiceConnection {
        override fun onServiceConnected(className: ComponentName, service: IBinder) {
            serviceMessenger = Messenger(service)
            isServiceBound = true
            // 发送消息给 Service,传递 Activity 的 Messenger
            val msg = Message.obtain().apply {
                replyTo = activityMessenger
            }
            try {
                serviceMessenger?.send(msg)
            } catch (e: RemoteException) {
                e.printStackTrace()
            }
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            serviceMessenger = null
            isServiceBound = false
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        bindService(Intent(this, MyService::class.java), serviceConnection, Context.BIND_AUTO_CREATE)
    }

    override fun onDestroy() {
        super.onDestroy()
        if (isServiceBound) {
            unbindService(serviceConnection)
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:05:39