Android Service 使用bindservice和startservice 区别

目录

Serivce基础

     

什么是Service ?

基础使用

startService()方法启动一个Service

bindService()方法绑定一个Service

startService和bindService异同

生命周期

独立性

交互方式

总结

tartService和bindService混合使用

场景1:

场景2:

场景3:

场景4:

总结


Serivce基础

     

什么是Service ?

Android四大组件之一。

Service并不与用户产生UI交互。其他的应用组件可以启动Service,即便用户切换了其他应用,启动的Service仍可在后台运行。一个组件可以与Service绑定并与之交互,甚至是跨进程通信(IPC)。

基础使用

基础使用

有两种方式: startService() 和 bindService()

startService()方法启动一个Service

import android.app.Service
import android.content.Intent
import android.os.*
import android.util.Log
import android.widget.Toast
 
class HelloService : Service() {
    private var mServiceLooper: Looper? = null
    private var mServiceHandler: ServiceHandler? = null
 
    companion object {
        const val TAG = "HelloService"
    }
 
    private inner class ServiceHandler(looper: Looper) : Handler(looper) {
        override fun handleMessage(msg: Message) {
            Log.d(TAG, "handleMessage")
            try {
                Thread.sleep(5000)
            } catch (e: InterruptedException) {
                Thread.currentThread().interrupt()
            }
        }
    }
 
    override fun onCreate() {
        Log.d(TAG, "onCreate")
        val thread = HandlerThread(
            "ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND
        )
        thread.start()
 
        mServiceLooper = thread.looper
        mServiceHandler = ServiceHandler(mServiceLooper!!)
    }
 
    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        Log.d(TAG, "onStartCommand")
 
        val msg: Message? = mServiceHandler?.obtainMessage()
        msg?.arg1 = startId
        msg?.let {
            mServiceHandler?.sendMessage(msg)
        }
 
        return START_STICKY
    }
 
    override fun onBind(intent: Intent): IBinder? {
        Log.d(TAG, "onBind")
        return null
    }
 
    override fun onDestroy() {
        Log.d(TAG, "onDestroy")
        Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show()
    }
}

要在mainifest注册

<service
        android:name="composer.service.HelloService"
        android:exported="true"
        android:enabled="true" />

activity中使用:

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import composer.databinding.ActivityTestStartServiceBinding
import composer.service.HelloService
import kotlinx.android.synthetic.main.activity_test_start_service.*
class TestStartServiceActivity : AppCompatActivity() {
    lateinit var binding: ActivityTestStartServiceBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityTestStartServiceBinding.inflate(LayoutInflater.from(this))
        setContentView(binding.root)
        startMyService.setOnClickListener {
            val intent = Intent(baseContext, HelloService::class.java)
            startService(intent)
        }
        stopMyService.setOnClickListener {
            val intent = Intent(baseContext, HelloService::class.java)
            stopService(intent)
        }
    }
}

运行打出的日志:

onCreate --->   onStartCommand  --->  handleMessage --->  onDestory

bindService()方法绑定一个Service

import android.app.Service
import android.content.Intent
import android.os.*
import android.util.Log
import android.widget.Toast
 
class HelloService : Service() {
    private var mServiceLooper: Looper? = null
    private var mServiceHandler: ServiceHandler? = null
    private val countNumBinder = CountNumBinder()
 
    companion object {
        const val TAG = "HelloService"
    }
 
    inner class CountNumBinder: Binder() {
        fun getCount(): Int {
            Log.i(TAG, ">>>>>>getCount()");
            return 100;
        }
    }
 
    private inner class ServiceHandler(looper: Looper) : Handler(looper) {
        override fun handleMessage(msg: Message) {
            Log.d(TAG, "handleMessage")
            try {
                Thread.sleep(5000)
            } catch (e: InterruptedException) {
                Thread.currentThread().interrupt()
            }
        }
    }
 
    override fun onCreate() {
        Log.d(TAG, "onCreate")
        val thread = HandlerThread(
            "ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND
        )
        thread.start()
 
        mServiceLooper = thread.looper
        mServiceHandler = ServiceHandler(mServiceLooper!!)
    }
 
    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        Log.d(TAG, "onStartCommand")
 
        val msg: Message? = mServiceHandler?.obtainMessage()
        msg?.arg1 = startId
        msg?.let {
            mServiceHandler?.sendMessage(msg)
        }
 
        return START_STICKY
    }
 
    override fun onBind(intent: Intent): IBinder {
        Log.d(TAG, "onBind")
        return countNumBinder
    }
 
    override fun onDestroy() {
        Log.d(TAG, "onDestroy")
        Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show()
    }
}

activity中使用:

package composer.view
 
import android.app.Service
import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import composer.databinding.ActivityTestStartServiceBinding
import composer.service.HelloService
import kotlinx.android.synthetic.main.activity_test_start_service.*
 
class TestStartServiceActivity : AppCompatActivity() {
    lateinit var binding: ActivityTestStartServiceBinding
    var countNumBinder: HelloService.CountNumBinder? = null
 
    companion object {
        const val TAG = "HelloService activity"
    }
 
    private val conn = object: ServiceConnection {
 
        // Activity与Service断开连接时回调该方法
        @Override
        override fun onServiceDisconnected(name: ComponentName) {
            Log.d(TAG, ">>>>>>Service DisConnected");
        }
 
        //Activity与Service连接成功时回调该方法
        @Override
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            Log.i(TAG, ">>>>>>Service Connected");
            countNumBinder =  service as HelloService.CountNumBinder
            Log.i(TAG, ">>>>>>Service Connected: " + countNumBinder?.getCount());
        }}
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityTestStartServiceBinding.inflate(LayoutInflater.from(this))
        setContentView(binding.root)
 
        startMyService.setOnClickListener {
            val intent = Intent(baseContext, HelloService::class.java)
            startService(intent)
        }
 
        stopMyService.setOnClickListener {
            val intent = Intent(baseContext, HelloService::class.java)
            stopService(intent)
        }
 
        bindMyService.setOnClickListener {
            val intent = Intent(baseContext, HelloService::class.java)
            bindService(intent, conn, Service.BIND_AUTO_CREATE)
        }
    }
}

运行打出的日志:

onCreate --->   onBind  --->  Service Connected ---> getCount()  ---> Service Connected : 100

startService和bindService异同

生命周期

  • startService方式:

可以多次调用,但是onCreate()只执行一遍,也就是Service只会创建一次,每次调用onStartCommand都会被调用。

该方式Service的生命周期为onCreate() -> onStartCommandonDestroy 。

  • bindService方式:

只有第一次调用会创建Service,执行onCreate()和onBind(),连续多次调用并不会执行onCreate()和onBind();

onCreate()->onBind()onUnBind

独立性

  • startService方式:

Service一旦被启动,在调用者没有调用stopService()的前提下,其生命周期就和调用者的生命周期不再关联。即使调用者被杀掉,Service也可以独立生存。

  • bindService方式:

与startService方式不同的是,这种方式,service的生命周期是和调用者关联在一起的,如果调用者进程被终结后,服务便会终止。

交互方式

  • startService之后可以发送action与服务交互。
  • bindService之后,除了发送action还 可以获得服务的完整方法(Binder的实现类),可以直接交互;

总结

startservice启动服务后,程序退出stopservice,服务依旧存在。

而bindservice启动服务后程序退出unbindservice,服务就会销毁。

而同时调用两种方法启动同一个方法,只会启动一个服务,但是其生命周期有所不同,取决于两种方法启动服务的先后顺序。

=========================================================================

tartService和bindService混合使用

tips:

bindService与startService同时执行创建的是同一个Service实例,因为onCreate只执行了一次。

bindService+startService的方式可以同时享受两者的优点,可以持久后台运行并且可以通过调用者操作Service。

场景1:

startService bindService & unbindServiced stopService

生命周期:

onCreate – onStartCommand – onBind – onUnbind–onDestroy

开始  --- >   运行startService,bindService开启服务

结束  --- >   运行unbindServiced,stopService结束服务

场景2:

startService bindSErvice & 销毁调用者(activity销毁等)

生命周期:

onCreate – onStartCommand – onBind – onUnbind(调用者销毁时)-- onDestroy(后台持续运行,直到被系统回收或者用户强制销毁服务)

这里 调用者销毁后,服务解绑,未销毁Service。

场景3:

bindService startService & unbindService stopService

生命周期:

onCreate – onBind – onStartCommand – onUnbind – onDestroy

bindService先运行,onBind将先与onStartCommand执行

结束  --》执行unbindService,stopService,正常销毁服务。

场景4:

bindService startService & 销毁调用者(activity销毁等)

生命周期:

onCreate – onBind – onStartCommand – onUnbind (销毁调用者时)-- onDestroy(后台持续运行,直到被系统回收或者用户强制销毁服务)

总结

用bindService+startService的方式可以同时享受两者的优点,可以持久后台运行并且可以通过调用者操作Service。

示例代码:

		stopBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unbindService(myConnection);
                stopService(serviceOne);
            }
        });
        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bindService(serviceOne,myConnection,BIND_AUTO_CREATE);
                startService(serviceOne);
            }
        });

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值