Android Service和Activity间的通信(binder和EventBus)

Service和Activity间的通信

  • Activity传递数据到Service
    使用Intent
  • Service传递数据到Activity
    使用Binder
    使用EventBus

使用Binder通信

  • MainActivity
    private fun initView() {
    	MyService.start(this)
        MyService.bind(this) {
            Log.d(TAG, "initView: $it")
        }
    }
  • MyService
class MyService : Service() {

    companion object {

        private const val TAG = "MyService"

        var starter: Intent? = null

        fun start(context: Context) {
            if (starter == null) {
                starter = Intent(context, MyService::class.java)
            }
            context.startService(starter)
        }

        fun stop(context: Context) {
            starter?.let {
                context.stopService(starter)
            }
        }

        var listener: (num: Int) -> Unit = {}

        var connection = object : ServiceConnection {
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                Log.e(TAG, "onServiceConnected: ")
                val simpleBinder = service as SimpleBinder
                simpleBinder.onListener = listener
            }

            override fun onServiceDisconnected(name: ComponentName?) {
                Log.e(TAG, "onServiceDisconnected: " )
            }
        }

        fun bind(context: Context, listener: (num: Int) -> Unit = {}) {
            this.listener = listener
            if (starter == null) {
                starter = Intent(context, MyService::class.java)
            }
            context.bindService(starter, connection, BIND_AUTO_CREATE)
        }

        fun unbind(context: Context) {
            context.unbindService(connection)
        }

    }

    private val simpleBinder: SimpleBinder by lazy { SimpleBinder() }

    override fun onBind(intent: Intent?): IBinder {
        return simpleBinder
    }

    var job: Job? = null

    override fun onCreate() {
        super.onCreate()
        job = GlobalScope.launch {
            repeat(20) {
                Log.d(TAG, "onCreate: $it")
                simpleBinder.onListener.invoke(it)
                delay(1000)
            }
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.e(TAG, "onStartCommand: " )
        return super.onStartCommand(intent, flags, startId)
    }


    override fun onDestroy() {
        super.onDestroy()
        //停止协程
        job?.cancel()
        Log.e(TAG, "onDestroy: ")
    }

}

class SimpleBinder : Binder() {
    var onListener: (num: Int) -> Unit = {}
}
  • 打印信息
D/MainActivity: initView: 0
D/MainActivity: initView: 1
D/MainActivity: initView: 2
...

另一个简洁版的

  • RemoteActivity
class RemoteActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_remote)
    }

    fun onClick(view: View) {
        RemoteService.bind(this) {
            Log.d(TAG, "onClick: $it")
        }
    }
}
  • RemoteService
class RemoteService : Service() {

    companion object{
        fun bind(context: Context,listener: (num: Int) -> Unit){
            context.bindService(Intent(context, RemoteService::class.java), object : ServiceConnection {
                override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                    val simpleBinder = service as SimpleBinder
                    simpleBinder.onListener = listener
                }

                override fun onServiceDisconnected(name: ComponentName?) {
                    TODO("Not yet implemented")
                }
            }, BIND_AUTO_CREATE)
        }
    }

    private val simpleBinder: SimpleBinder by lazy { SimpleBinder() }

    override fun onBind(intent: Intent): IBinder {
        return simpleBinder
    }

    private lateinit var job:Job

    override fun onCreate() {
        super.onCreate()
        job = GlobalScope.launch {
            repeat(20) {
                Log.d(TAG, "onCreate: $it")
                simpleBinder.onListener.invoke(it)
                delay(1000)
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        job.cancel()
    }
}

class SimpleBinder : Binder() {
    var onListener: (num: Int) -> Unit = {}
}

多进程中的问题

  • 我们将RemoteService放入单独的一个进程中
        <service
            android:name=".remote.RemoteService"
            android:process=":remote"
            android:enabled="true"
            android:exported="true" />
  • 此时出现异常
    Process: com.zhangyu.myservice, PID: 28693
    java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.zhangyu.myservice.remote.SimpleBinder
        at com.zhangyu.myservice.remote.RemoteService$Companion$bind$1.onServiceConnected(RemoteService.kt:25)
        at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1956)
        at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1988)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7562)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值