Android学习总结之service篇

引言

在 Android 开发里,Service 与 IntentService 是非常关键的组件,它们能够让应用在后台开展长时间运行的操作。不过,很多开发者仅仅停留在使用这两个组件的层面,对其内部的源码实现了解甚少。本文将深入剖析 Service 和 IntentService 的源码,揭示它们的工作原理与区别。

Service 源码剖析

1. Service 概述

Service 是 Android 四大组件之一,用于在后台执行长时间运行的操作,且不提供用户界面。它可以通过 startService() 启动,也能通过 bindService() 绑定,从而与其他组件进行交互。

2. 生命周期方法

Service 的生命周期方法定义在 android.app.Service 类中,主要包含 onCreate()、onStartCommand()、onBind() 和 onDestroy()。

java 复制代码
Service
├─ onCreate()          // 初始化(仅一次)
├─ onStartCommand()    // 处理 startService 请求(可多次调用)
├─ onBind()            // 处理 bindService 请求(返回 IBinder)
├─ onDestroy()         // 释放资源
└─ 需手动管理子线程    // 耗时操作需自行创建线程
  • onCreate():服务创建时调用,通常用于初始化操作,此方法仅调用一次。
  • onStartCommand() :每次调用 startService() 启动服务时都会调用该方法,其返回值决定了服务在被系统杀死后的重启策略。
  • onBind() :当调用 bindService() 时调用,需要返回一个 IBinder 对象,用于与服务进行通信。
  • onDestroy():服务销毁时调用,可用于释放资源。
java 复制代码
    A[Service 生命周期] --> B[onCreate()]
    B --> C{启动方式}
    C -->|startService()| D[onStartCommand()]
    C -->|bindService()| E[onBind()]
    D --> F[手动调用 stopSelf()/stopService()]
    E --> G[解绑时 onUnbind()]
    F & G --> H[onDestroy()]

    I[IntentService 生命周期] --> J[onCreate()]
    J --> K[创建 HandlerThread & ServiceHandler]
    K --> L[onStartCommand() 调用 onStart()]
    L --> M[ServiceHandler 处理 Message]
    M --> N[调用 onHandleIntent(intent)(子线程)]
    N --> O[自动调用 stopSelf()]
    O --> P[onDestroy()(Looper.quit())]

3. 启动流程

当调用 startService() 方法时,最终会调用到 ActivityManagerService 中的相关方法,它会负责创建 Service 实例并调用其生命周期方法。

java 复制代码
// ActivityManagerService.java
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, int userId) {
    // 处理启动服务的逻辑
    synchronized(this) {
        // ...
        ServiceRecord r = startServiceLocked(caller, service, resolvedType, callingPid,
                callingUid, userId);
        // ...
    }
    // ...
}

4. 注意事项

Service 默认在主线程中运行,若在 Service 中执行耗时操作,会导致界面卡顿。因此,若有耗时操作,应在 Service 中手动创建子线程。

IntentService 源码剖析

1. IntentService 概述

IntentService 是 Service 的子类,它是一个异步的、会自动停止的服务。它内部使用 HandlerThread 创建了一个子线程,所有的 Intent 都会在这个子线程中处理。

2. 关键源码分析

java 复制代码
IntentService(继承 Service)
├─ onCreate()          
│  └─ 创建 HandlerThread(子线程)
│  └─ 获取 Looper,创建 ServiceHandler(绑定子线程 Looper)
├─ onStartCommand()    
│  └─ 调用 onStart(),将 Intent 封装为 Message 发送给 ServiceHandler
├─ ServiceHandler(Handler 子类)
│  └─ handleMessage():调用 onHandleIntent() 处理 Intent,调用 stopSelf()
├─ onHandleIntent()     // 开发者需实现的核心业务逻辑(在子线程执行)
└─ onDestroy()         
   └─ 调用 Looper.quit() 终止子线程
java 复制代码
// android.app.IntentService
public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

    public IntentService(String name) {
        super();
        mName = name;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }

    protected abstract void onHandleIntent(@Nullable Intent intent);
}

3. 关键流程

  • onCreate() :创建一个 HandlerThread 并启动它,然后获取该线程的 Looper,创建一个 ServiceHandler 并关联该 Looper。
  • onStartCommand() :调用 onStart() 方法,将传递的 Intent 封装成 Message 发送给 ServiceHandler。
  • ServiceHandler 的 handleMessage() :调用 onHandleIntent() 方法处理 Intent,处理完成后调用 stopSelf() 停止服务。

4. 特点总结

  • 异步处理 :所有的 Intent 都会在子线程中处理,避免了在主线程中执行耗时操作。
  • 自动停止 :当所有的 Intent 处理完成后,IntentService 会自动调用 stopSelf() 方法停止服务。
  • 顺序处理 :IntentService 会按照 Intent 到达的顺序依次处理,不会并发处理多个 Intent。

Service 与 IntentService 的区别

1. 线程方面

  • Service 默认在主线程中运行,若要执行耗时操作,需手动创建子线程。
  • IntentService 内部创建了一个子线程,所有的 Intent 都会在该子线程中处理。

2. 停止方式

  • Service 需要手动调用 stopSelf() 或 stopService() 来停止服务。
  • IntentService 在处理完所有的 Intent 后会自动停止。

3. 处理方式

  • Service 可以同时处理多个请求。
  • IntentService 会按顺序依次处理 Intent,不会并发处理。

总结图表

特性 Service IntentService
继承关系 直接继承 ContextWrapper,实现 ComponentCallbacks2 继承自 Service,是 Service 的子类
线程环境 默认运行在主线程(UI 线程),需手动创建子线程处理耗时任务 内部创建 HandlerThread 子线程,通过 ServiceHandler 在子线程处理所有 Intent
启动后的处理逻辑 需重写 onStartCommand,手动处理业务逻辑,需手动调用 stopSelf() 停止服务 自动将 Intent 封装为 Message,通过 ServiceHandler 按顺序处理,处理完自动停止
生命周期控制 需手动调用 stopService() 或 stopSelf() 停止,或通过 onStartCommand 返回值控制重启策略 无需手动停止,处理完所有 Intent 后自动调用 stopSelf() 停止
并发处理 可同时处理多个 startService 请求(需自行处理多线程同步) 按 Intent 接收顺序串行处理,同一时间仅处理一个 Intent
默认 onBind 返回值 返回 null(需开发者自定义 IBinder) 直接返回 null(不支持绑定,如需绑定需自定义子类)
适用场景 复杂后台逻辑(如跨组件通信、长期运行任务) 简单异步任务(如网络请求、文件操作),任务完成后自动停止

结论

若需要执行简单的异步任务且任务完成后自动停止服务,可选择 IntentService;若需要与其他组件进行交互或同时处理多个请求,则可选择 Service。

感谢观看!!!

相关推荐
m4Rk_4 分钟前
【论文阅读】Agent 记忆机制(113):Agentic Memory Management——从“检索相关信息”走向“管理 Agent 内部记忆”
论文阅读·人工智能·学习·开源·github
辣知1 小时前
辣知·化智92 《山海经》里的史前密码
学习
鬼手点金1 小时前
KV Cache 未必是一次性的:可编辑、可组合的“笔记”
java·人工智能·笔记·学习·自动化·1024程序员节
kyrie_sakura2 小时前
大模型学习18 大模型学习 - LangChain2_Model I/O
学习·自然语言处理
TimeFine3 小时前
AI 编码工作流的设计
android·ai编程
宝绿特塑业再生科技3 小时前
板材收缩率不稳,户外家具装配尺寸为何对不上:从切割尺寸变化到接缝不一的系统性排查与对策
笔记·科技·学习·生活·户外家具·hdpe再生颗粒·hdpe
骑着蜗牛撵大象3273 小时前
C++20 协程 × 屏障:手写一个 co_await 版 Barrier,让等待不再钉死线程
android·c++20·协程·并发编程·co_await·屏障同步
~城南花已开~4 小时前
Intel E810 SR-IOV VF Spoofcheck 防伪造测试-KVM3
服务器·网络·笔记·学习·ubuntu·etl工程师
山东孙燕姿5 小时前
设备台账重构:从一张表到三层模型
android·java·网络·低代码·重构·rxjava
我命由我123456 小时前
6-3.Python 异常处理 - 异常处理进阶(else 块与 finally 块、异常传递、自定义异常)
开发语言·前端·数据库·后端·python·学习·java-ee