Skip to content

后台服务

本文讲述启动后台服务用法。 调用startService方法启动服务。同时演示如何停止服务。

本文中的 服务/Service 指的是后台服务。

本文的示例使用Kotlin实现。

新建服务

我们新建一个ServiceStartDemo类继承Service

class ServiceStartDemo : Service() {

    companion object {
        const val TAG = "rustAppStartDemoService"
    }

    override fun onCreate() {
        super.onCreate()
        Log.d(TAG, "onCreate ${Thread.currentThread()}")
    }

    override fun onBind(intent: Intent): IBinder? {
        Log.d(TAG, "onBind ${Thread.currentThread()}")
        return null
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(TAG, "onStartCommand flags:$flags, startId:$startId [$this] ${Thread.currentThread()}")
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy [$this] ${Thread.currentThread()}")
    }
}

  • 在各个生命周期方法中我们打上log,便于后续观察
    • log中打出服务对象的详细信息,线程信息等等
  • onBind方法中我们返回null,表明这个服务不能用bindService的方式启动

AndroidManifest.xml中注册这个服务

<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
  <!-- ... -->
  <application>
    <service
        android:name=".service.start.ServiceStartDemo"
        android:enabled="true"
        android:exported="false" />
            <!-- ... -->
  </application>
</manifest>

注意

  • name是我们的服务的类名。它是唯一必需的属性
  • enabledtrue,表明系统可以示例化这个服务。默认值为true
    • application也有自己的enabled属性,默认值为true。该属性适用于所有应用组件,包括服务
  • exported这里设置为false,表明不给其他进程(app)使用,仅适用于我们这个app

这样我们的服务就准备完毕了。

startService启动服务

在activity中调用startService方法,启动服务。

startService(Intent(applicationContext, ServiceStartDemo::class.java))

调用方法后,ServiceStartDemo服务会启动起来。 首次启动的话,服务会走onCreateonStartCommand方法。 初始化性质的代码,放在onCreate里。

服务已经存在的情况下,用startService方法启动服务,服务会走onStartCommand方法。 此时onStartCommand里的startId会自增。用这个数值可以看出这个Service对象被启动了多少次。

同时我们可以在Service的log里观察到,Service的生命周期函数是在主线程中执行的。 因此Service也可能会遇到ANR问题。不能把过于耗时的任务放在生命周期函数里。

Activity与Service沟通

Activity与Service是相互独立的组件。用startService方法启动服务并不会让activity持有service的实例。 它们之间可以用广播来进行沟通。或者用EventBus之类的工具进行沟通。

停止服务

完成任务后,我们可以停止服务。节省系统资源。 前面是用startService方法启动的服务,后面用stopService(Intent)来停止服务。

方法 介绍
stopService(Intent) Activity或其他组件调用这个方法,停止目标service
stopSelf() Service调用这个方法来停止自己

例如在Activity中

stopService(Intent(applicationContext, ServiceStartDemo::class.java))

在Service中

stopSelf()

一旦请求使用 stopSelf()stopService() 来停止服务,服务会走onDestroy()方法。 系统会尽快销毁服务。

作者: RustFisher
联系: rf.cs@foxmail.com
博客: rustfisher.com | RustFisher cnblog
示例: AndroidTutorial Gitee, Tutorial Github
链接: https://www.an.rustfisher.com/android/service/start/background-service/
一家之言,仅当抛砖引玉。如有错漏,还请指出。