Service的两种使用方式比较 startService和bindService

虽然说Android 有四大组件,但是大部分Androider只会使用Activity,其他的组件只有自己踩坑学习的时候才会去弄明白。我会用代码+日志的方式帮助你理解这两种使用方式的区别。

1 清单文件声明FirstService类

<application
        ...
        <service
            android:name=".FirstService"
            android:enabled="true"
            android:exported="false">
        </service>
        ...
    </application>

2 新增 FirstService.kt

class FirstService : Service() {
    
    companion object{
        const val TAG = "FirstService"
    }
    inner class MyBinder : Binder() {
        val service: FirstService
            get() = this@FirstService
    }

    override fun onCreate() {
        Log.i(TAG, "onCreate")
        super.onCreate()
    }

    override fun onBind(intent: Intent): IBinder? {
        Log.i(TAG, "onBind")
        return MyBinder()
    }

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

    override fun onDestroy() {
        Log.i(TAG, "onDestroy")
        super.onDestroy()
    }

    override fun onUnbind(intent: Intent): Boolean {
        Log.i(TAG, "onUnbind")
        return super.onUnbind(intent)
    }
}

3 MainActvivity启动Service

class MainActivity : AppCompatActivity(), View.OnClickListener {
    private var mStart: Button? = null
    private var mStop: Button? = null
    private var mBind: Button? = null
    private var mUnbind: Button? = null
    private var mBinder: FirstService.FirstBinder? = null
    private val mServiceConnection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            mBinder = (service as FirstService.FirstBinder)
        }

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

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mStart = findViewById<View>(R.id.startService) as Button
        mStop = findViewById<View>(R.id.stopService) as Button
        mBind = findViewById<View>(R.id.bindService) as Button
        mUnbind = findViewById<View>(R.id.unBindService) as Button
        mStart!!.setOnClickListener(this)
        mStop!!.setOnClickListener(this)
        mBind!!.setOnClickListener(this)
        mUnbind!!.setOnClickListener(this)
    }

    private fun stopService() {
        val intent = Intent(this@MainActivity, FirstService::class.java)
        stopService(intent)
    }

    private fun startService() {
        val intent = Intent(this@MainActivity, FirstService::class.java)
        startService(intent)
    }

    override fun onClick(v: View) {
        when (v.id) {
            R.id.startService -> startService()
            R.id.stopService -> stopService()
            R.id.bindService -> bindService()
            R.id.unBindService -> unbindService(mServiceConnection)
        }
    }

    private fun bindService() {
        val intent = Intent(this@MainActivity, FirstService::class.java)
        bindService(intent, mServiceConnection, BIND_AUTO_CREATE)
    }
}

4 开始测试

( 我们的界面如下所示,后面的截图都是在此基础上)
这里写图片描述
前面铺垫很多啦,接下来我们开始测试!

4.1 startService -> stopService

这里写图片描述

4.2 bindService -> unBindService

这里写图片描述

4.3 startService -> startService -> stopService-> stopService

多次执行startService 并没有按照我们的常规思维多次创建 service,而是 只创建1次Service,然后重复调用onStartCommand而已,多次调用stopService也只是关闭1次 Service而已。
这里写图片描述

4.4 bindService -> bindService -> unBindService-> unBindService

和4.3相类似,多次调用bindService也是只创建1次Service
但是不会重复调用onBind, unBindService重复调用会引发Crash 需要注意

4.5 startService -> bindService -> unBindService-> stopService

注意:当点击解绑服务的时候只显示了“onUnbind”,直到点击停止服务才显示“onDestory”
这里写图片描述

4.6 startService -> bindService -> stopService ->unBindService

注意:点击停止服务的时候什么都没有打印出来,当点击解绑任务的时候才连续出现“onUnbind”“onDestory”
这里写图片描述

4.7 bindService -> startService -> unBindService -> stopService

先执行的onBind再执行的onStartCommand
注意:解绑服务时候只显示了“onUnbind”,点击停止服务的时候才显示的“onDestory”
这里写图片描述

4.8 bindService -> startService -> stopService -> unBindService

注意:停止服务的时候什么都没有显示,但是解绑服务的时候显示出了“onUnbind”“onDestory”
这里写图片描述

4.9 (startService 或 bindService) 与Activity 的关系

假设在一个 Activity中启动了MyService服务,然后再Finish 这个 Activity ,MyService该如何执行呢?

4.9.1 startService

点击"启动服务"然后退出Activity 注意并没有执行 Service的 destory方法,此时页面已经被销毁了但是Service还存在
在这里插入图片描述

4.9.2 bindService

点击绑定服务然后退出Activity(并没有调用unBindService方法)但是执行了Service的 Destory,此时页面已经被销毁了,Service也已经被销毁了
在这里插入图片描述

5 总结两种启动方式

Service只会创建一次

再次start / bind也不会创建新的Service

startService 简单粗暴,小心内存泄露

startService使用很简单粗暴但是需要关心这个Service是否应该销毁stopService

bindService使用麻烦但是功能强大

可以自动解绑和Binder通信, IPC通信(AIDL Messenger)都是基于这个 Service的 bindService

成对创建就得等成对销毁

start+bind同时创建就得等unbind+stop同时销毁, 可以理解为监听器有两个,必须都移除掉之后才可以销毁对象

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值