美文网首页
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浅谈(一)

    一、概述 ​ Service是Android四大组件之一,是一段长生命周期但是没有用户界面的组件,用来做播放音...

  • 浅谈Android Service

    Service 服务 什么是服务: A service is not a separate process and...

  • 浅谈 Android Service

    前言:本文所写的是博主的个人见解,如有错误或者不恰当之处,欢迎私信博主,加以改正!原文链接,demo链接 Serv...

  • android知识学习 - 收藏集 - 掘金

    浅谈 Android Service - 掘金前言:本文所写的是博主的个人见解,如有错误或者不恰当之处,欢迎私信博...

  • 浅谈 kubernetes service 那些事 (下篇)

    欢迎访问网易云社区,了解更多网易技术产品运营经验。 五、K8s 1.8 新特性——ipvs ipvs与iptabl...

  • 浅谈 kubernetes service 那些事(上篇)

    欢迎访问网易云社区,了解更多网易技术产品运营经验。 一、问题 首先,我们思考这样一个问题: 访问k8s集群中的po...

  • 浅谈Filecoin(二)

    浅谈Filecoin(二) 浅谈Filecoin(一)链接:浅谈Filecoin(一) (Verifiable)M...

  • 2020-07-02

    浅谈 浅谈模块设计宏内核 浅谈接口设计Flags 浅谈稳定性设计重试 浅谈人员业务结构设计矩阵式 浅谈接口设计 |...

  • 浅谈Service Mesh体系中的Envoy

    摘要:提到Envoy就不得不提Service Mesh,说到Service Mesh就一定要谈及微服务了,那么我们...

  • Android - Service(一)Service 初步

    Service 是什么 Service,服务,Android 四大组件之一;Service 是一个应用组件,它没有...

网友评论

      本文标题:Service浅谈(一)

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