一文带你吃透Android中Service的种类和启动方式!!!!

98 阅读3分钟

在 Android 中,Service 是一种可以在后台执行长时间运行操作的组件,它没有用户界面。Service 的种类和启动方式是其核心概念之一。以下是 Android 中 Service 的种类及其启动方式的详细说明:

一、Service 的种类

1.1、 普通 Service(Started Service)

  • 特点

    • 通过 startService() 启动。
    • 即使启动它的组件(如 Activity)被销毁,Service 仍会继续运行。
    • 适用于执行一次性任务(如下载文件)。
  • 生命周期方法

    • onCreate():Service 创建时调用。
    • onStartCommand():每次通过 startService() 启动时调用。
    • onDestroy():Service 销毁时调用。

1.2、 绑定 Service(Bound Service)

  • 特点

    • 通过 bindService() 启动。
    • 允许多个组件绑定到同一个 Service,并与 Service 进行交互。
    • 当所有绑定组件解绑后,Service 会自动销毁。
    • 适用于需要与组件交互的场景(如音乐播放器)。
  • 生命周期方法

    • onCreate():Service 创建时调用。
    • onBind():组件绑定时调用,返回一个 IBinder 对象用于通信。
    • onUnbind():所有组件解绑时调用。
    • onDestroy():Service 销毁时调用。

1.3、 前台 Service(Foreground Service)

  • 特点

    • 通过 startForeground() 启动。
    • 在状态栏显示一个持续的通知,告知用户 Service 正在运行。
    • 适用于需要用户感知的后台任务(如音乐播放、文件下载)。
  • 生命周期方法

    • 与普通 Service 相同,但需要调用 startForeground() 显示通知。
  • 注意事项

    • 从 Android 8.0(API 26)开始,前台 Service 必须通过 startForegroundService() 启动。

1.4、 IntentService(已过时)

  • 特点

    • 是 Service 的子类,用于处理异步任务。
    • 在后台线程中执行任务,任务完成后自动停止。
    • 适用于需要顺序执行的任务队列。
  • 生命周期方法

    • onHandleIntent():在后台线程中处理传入的 Intent。
  • 注意事项

    • 从 Android 8.0 开始,IntentService 已被弃用,推荐使用 WorkManager 或 JobScheduler

二、 Service 的启动方式

2.1、 通过 startService() 启动

  • 用途:启动普通 Service 或前台 Service。

  • 特点

    • Service 会一直运行,直到调用 stopSelf() 或其他组件调用 stopService()
    • 适用于不需要与组件交互的任务。
  • 代码示例

Intent intent = new Intent(this, MyService.class);
startService(intent);

2.2、 通过 bindService() 启动

  • 用途:启动绑定 Service。

  • 特点

    • Service 与组件绑定,组件可以通过 IBinder 与 Service 交互。
    • 当所有绑定组件解绑后,Service 会自动销毁。
  • 代码示例

Intent intent = new Intent(this, MyBoundService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
  • ServiceConnection 示例:
private ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        MyBoundService.MyBinder binder = (MyBoundService.MyBinder) service;
        MyBoundService myService = binder.getService();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
};

2.3、 通过 startForegroundService() 启动

  • 用途:启动前台 Service。

  • 特点

    • 从 Android 8.0 开始,必须使用 startForegroundService() 启动前台 Service。
    • 需要在 onStartCommand() 中调用 startForeground() 显示通知。
  • 代码示例

Intent intent = new Intent(this, MyForegroundService.class);
startForegroundService(intent);
  • startForeground() 示例:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("Service Running")
        .setContentText("Foreground Service is running")
        .setSmallIcon(R.drawable.ic_notification)
        .build();
    startForeground(1, notification);
    return START_STICKY;
}

三、Service 的生命周期

3.1、普通 Service 的生命周期

  • onCreate() → onStartCommand() → onDestroy()

3.2、绑定 Service 的生命周期

  • onCreate() → onBind() → onUnbind() → onDestroy()

3.3、前台 Service 的生命周期

  • 与普通 Service 相同,但需要调用 startForeground()

四、Service 的停止方式

4.1、停止普通 Service

  • 在 Service 内部调用 stopSelf()
  • 在其他组件中调用 stopService()

4.2、停止绑定 Service

  • 调用 unbindService() 解绑。
  • 当所有绑定组件解绑后,Service 会自动销毁。

4.3、停止前台 Service

  • 调用 stopForeground(true) 停止前台状态。
  • 调用 stopSelf() 停止 Service。

五、注意事项

5.1、后台限制:

  • 从 Android 8.0 开始,后台 Service 受到限制,推荐使用 JobScheduler 或 WorkManager

5.2、权限:

  • 前台 Service 需要 FOREGROUND_SERVICE 权限。
  • 从 Android 10 开始,后台启动 Service 需要 START_ACTIVITIES_FROM_BACKGROUND 权限。

5.3、性能优化:

  • 避免在 Service 中执行耗时操作,推荐使用线程或协程。

通过以上内容,你可以全面了解 Android 中 Service 的种类、启动方式及其生命周期,从而根据需求选择合适的 Service 类型和启动方式。

更多分享

  1. 一文带你吃透Kotlin协程的launch()和async()的区别
  2. 一文吃透Kotlin中冷流(Clod Flow)和热流(Hot Flow)
  3. 一文带你吃透Android中常见的高效数据结构
  4. 一文带你顺利完成从 Groovy 到 Kotlin DSL 的迁移