美文网首页
Service浅谈(一)

Service浅谈(一)

作者: dw_0920 | 来源:发表于2019-07-15 16:47 被阅读0次

    一、概述

    ​ Service是Android四大组件之一,是一段长生命周期但是没有用户界面的组件,用来做播放音乐、监控状态之类的后台操作,也可以将应用的某种功能暴露给其他程序。

    二、生命周期

    官方给出的Service生命周期如下:

    我们先来看各种回调方法的含义:

    • onCreate():

      首次创建服务的时候,系统将调用此方法。若服务已经开启,则不会再回调,只执行一次。

    • onStartCommand():

      当组件通过调用startService()启动Service时回调方法。

    • onBind():
      当组件通过调用bindService()与Service绑定时回调方法。

    • onUnbind():
      当组件通过调用unbindService()与Service解绑时回调方法。

    • onDestroy():
      当Service销毁时回调方法。

    从上图我们可以知道Service有两种方法可以启动,而这两种方法也可以穿插着进行,下面我们通过输出来直观地看一看,代码如下:

    MainActivity:

    class MainActivity : AppCompatActivity() {
        private val TAG = "ITestServiceTag"
        private val serviceConnection = object :ServiceConnection{
            override fun onServiceDisconnected(name: ComponentName?) {
                Log.d(TAG,"执行方法----onServiceDisconnected()")
            }
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                Log.d(TAG,"执行方法----onServiceConnected()")
            }
        }
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            val intent = Intent(this,ITestService::class.java)
            startService.setOnClickListener {
                Log.d(TAG,"点击按钮----startService")
                startService(intent)
            }
            stopService.setOnClickListener{
                Log.d(TAG,"点击按钮----stopService")
                stopService(intent)
            }
            bindService.setOnClickListener {
                Log.d(TAG,"点击按钮----bindService")
                bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE)
            }
            unBindService.setOnClickListener {
                Log.d(TAG,"点击按钮----unBindService")
                unbindService(serviceConnection)
            }
        }
    }
    

    ITestService:

    class ITestService : Service() {
        private val TAG = "ITestServiceTag"
        override fun onBind(intent: Intent?): IBinder? {
            Log.d(TAG,"执行方法----onbind()")
            return null
        }
    
        override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
            Log.d(TAG,"执行方法----onStartCommand()")
            return super.onStartCommand(intent, flags, startId)
        }
    
        override fun onCreate() {
            super.onCreate()
            Log.d(TAG,"执行方法----onCreate()")
        }
    
        override fun onUnbind(intent: Intent?): Boolean {
            Log.d(TAG,"执行方法----onUnbind()")
            return super.onUnbind(intent)
        }
    
        override fun onDestroy() {
            super.onDestroy()
            Log.d(TAG,"执行方法----onDestroy()")
        }
    }
    

    输出结果如下:

    1. startService() —> bindService() —> stopService() —> unbindService()
    service1.png
    1. bindService() —>startService() —> unbindService() —>stopService()
    service4.png

    ​ 从上面两个结果我们可以知道,当Service通过调用bindService()方法处于绑定状态时,调用stopService()方法不会结束Service,而是等到Service解除绑定状态后才会将Service结束并销毁。
    ​ 通过以上介绍及结果,我们可以得出以下结论:

    a. startService() —>…—>stopService() :
    onCreate() —>onStartCommand()—>…—>onDestroy()

    b. bindService() —>unbindService() :
    onCreate() —>onBind() —>onUnBind()—>onDestroy()

    c. startService() —> bindService() —> stopService() —> unbindService():
    onCreate() —>onStartCommand()—>onBind() —>onUnBind()—>onDestroy()

    三、Activity和Service交互

    ​ Activity传递数据到Service最主要且最方便就是通过Intent来实现,在这里我们不做赘述,主要说一说Service如何向Activity传递数据。

    1. 通过Binder

    ​ 经过上面的讲解,我们知道创建一个Service的时候,都必须实现onBind()方法的,该方法会返回一个IBinder类型的对象,IBinder是Android进程间通信的核心部分,在这里,他也可以用来进行进程内通信。在onBind方法中返回的IBinder对象,会作为调用bindService(Intent service, ServiceConnection conn,int flags)方法时,ServiceConnection接口下onServiceConnected(ComponentName name, IBinder service)方法的参数返回。

    ​ 下面我们用一个简单的例子实现一下:

    ITestService:

    class ITestService : Service() {
        private val TAG = "ITestServiceTag"
        override fun onBind(intent: Intent?): IBinder? {
            return ITestBinder()
        }
        fun showMsg() {
            Toast.makeText(this, "回调成功$TAG", Toast.LENGTH_LONG).show()
        }
    
        inner class ITestBinder : Binder() {
            var iTestService = this@ITestService
            fun showMsg() {
                iTestService.showMsg()
            }
        }
    }
    

    MainActivity:

    class MainActivity : AppCompatActivity() {
        private var binderService: ITestService.ITestBinder? = null
        private val serviceConnection = object :ServiceConnection{
            override fun onServiceDisconnected(name: ComponentName?) {
            }
    
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                binderService = service as ITestService.ITestBinder?
                binderService?.showMsg()
            }
        }
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            val intent = Intent(this,ITestService::class.java)
            bindService.setOnClickListener {
                bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE)
            }
            unBindService.setOnClickListener {
                unbindService(serviceConnection)
            }
        }
    }
    

    ​ 在onBind()方法中返回的IBinder对象主要是为了能够让组件获取到Service对象,从而可以调用Service里面的回调方法和变量。

    2. 通过Broadcast广播

    ​ 这种方法较为复杂,需要在Activity中创建一个BroadcastReceiver,在Service中发送广播。

    ITestService:

    class ITestService : Service() {
        override fun onBind(intent: Intent?): IBinder? {
            val intent = Intent()
            intent.action = "location.itest"
            sendBroadcast(intent)
            return null
        }
    }
    

    MainActivity:

    class MainActivity : AppCompatActivity() {
        private val iTestBroadcast = ITestBroadcast()
        private val serviceConnection = object :ServiceConnection{
            override fun onServiceDisconnected(name: ComponentName?) {
            }
    
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            }
        }
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
          //注册广播
            val filter = IntentFilter("location.itest")
            registerReceiver(iTestBroadcast,filter)
          
            val intent = Intent(this,ITestService::class.java)
            bindService.setOnClickListener {
                bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE)
            }
            unBindService.setOnClickListener {
                unbindService(serviceConnection)
            }
        }
    
        inner class ITestBroadcast : BroadcastReceiver(){
            private val TAG = "ITestServiceTag"
            override fun onReceive(context: Context?, intent: Intent?) {
                val intentAction = intent?.action
                if (intentAction == "location.itestr") {
                    Toast.makeText(this@MainActivity,"成功回调$TAG",Toast.LENGTH_LONG).show()
                }
            }
        }
    
        override fun onDestroy() {
            super.onDestroy()
            unregisterReceiver(iTestBroadcast)
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Service浅谈(一)

          本文链接:https://www.haomeiwen.com/subject/ovankctx.html