Android學習總結之service篇

引言

在 Android 開發里,Service?與?IntentService?是非常關鍵的組件,它們能夠讓應用在后臺開展長時間運行的操作。不過,很多開發者僅僅停留在使用這兩個組件的層面,對其內部的源碼實現了解甚少。本文將深入剖析?Service?和?IntentService?的源碼,揭示它們的工作原理與區別。

Service 源碼剖析

1. Service 概述

Service?是 Android 四大組件之一,用于在后臺執行長時間運行的操作,且不提供用戶界面。它可以通過?startService()?啟動,也能通過?bindService()?綁定,從而與其他組件進行交互。

2. 生命周期方法

Service?的生命周期方法定義在?android.app.Service?類中,主要包含?onCreate()onStartCommand()onBind()?和?onDestroy()

Service
├─ onCreate()          // 初始化(僅一次)
├─ onStartCommand()    // 處理 startService 請求(可多次調用)
├─ onBind()            // 處理 bindService 請求(返回 IBinder)
├─ onDestroy()         // 釋放資源
└─ 需手動管理子線程    // 耗時操作需自行創建線程
  • onCreate():服務創建時調用,通常用于初始化操作,此方法僅調用一次。
  • onStartCommand():每次調用?startService()?啟動服務時都會調用該方法,其返回值決定了服務在被系統殺死后的重啟策略。
  • onBind():當調用?bindService()?時調用,需要返回一個?IBinder?對象,用于與服務進行通信。
  • onDestroy():服務銷毀時調用,可用于釋放資源。
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?實例并調用其生命周期方法。

// 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. 關鍵源碼分析

IntentService(繼承 Service)
├─ onCreate()          
│  └─ 創建 HandlerThread(子線程)
│  └─ 獲取 Looper,創建 ServiceHandler(綁定子線程 Looper)
├─ onStartCommand()    
│  └─ 調用 onStart(),將 Intent 封裝為 Message 發送給 ServiceHandler
├─ ServiceHandler(Handler 子類)
│  └─ handleMessage():調用 onHandleIntent() 處理 Intent,調用 stopSelf()
├─ onHandleIntent()     // 開發者需實現的核心業務邏輯(在子線程執行)
└─ onDestroy()         └─ 調用 Looper.quit() 終止子線程
// 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);}@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent)msg.obj);stopSelf(msg.arg1);}}public IntentService(String name) {super();mName = name;}@Overridepublic void onCreate() {super.onCreate();HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);}@Overridepublic void onStart(@Nullable Intent intent, int startId) {Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);}@Overridepublic int onStartCommand(@Nullable Intent intent, int flags, int startId) {onStart(intent, startId);return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;}@Overridepublic void onDestroy() {mServiceLooper.quit();}@Override@Nullablepublic 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,不會并發處理。

總結圖表

特性ServiceIntentService
繼承關系直接繼承?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

感謝觀看!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76173.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76173.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76173.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ExternalProject_Add 使用手冊與文檔詳解

一、基本概念與語法 ExternalProject_Add 是 CMake 的一個核心命令,用于在構建過程中集成和管理外部項目(如第三方庫)。它支持完整的生命周期管理,包括下載、配置、構建、安裝和測試。 語法: ExternalProject_Add(&l…

低延遲云網絡的核心技術

低延遲云網絡通過架構優化、協議創新、硬件加速等多維度技術手段,將數據傳輸延遲降低至毫秒級甚至微秒級。 1. 網絡架構優化 1.1 扁平化網絡Leaf-Spine 架構 減少網絡層級,縮短數據轉發路徑(如數據中心內部一跳可達)。 扁平化網絡Leaf-Spine(葉子-脊椎)架構是一種現代…

網絡安全法規與入門指南

在當今數字化時代,網絡安全已成為保障個人隱私、企業利益和國家安全的關鍵領域。隨著網絡攻擊的日益復雜和頻繁,了解和遵守網絡安全法規變得尤為重要。本文將深入探討網絡安全相關法規,并為想要進入這一領域的讀者提供實用的入門指南。 一、…

硬盤分區格式方案之 MBR(Master Boot Record)主引導記錄的 主分區 和 擴展分區 筆記250407

硬盤分區格式方案之 MBR(Master Boot Record)主引導記錄的 主分區 和 擴展分區 筆記250407 一、主分區(Primary Partition) 1. 定義與功能 直接引導操作系統:主分區是獨立的存儲單元,可直接安裝操作系統并…

【Proteus仿真】【32單片機-A007】PT100熱敏溫度檢測系統設計

目錄 一、主要功能 二、使用步驟 三、硬件資源 四、軟件設計 五、實驗現象 聯系作者 一、主要功能 1、LCD1602顯示當前檢測的溫度值以及溫度閾值 2、超過上限溫度,降溫模塊啟動? 3、PT100熱敏電阻測量-60C-135C 4、按鍵設置溫度閾值 5、超過閾值&#xff0…

pyqt SQL Server 數據庫查詢-優化2

1、增加導出數據功能 2、增加刪除表里數據功能 import sys import pyodbc from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QListWidget, QLineEdit, QPushButton, \QTableWidget, QTableWidgetItem, QLabel, QMessageBox from PyQt6.QtGui i…

Github 熱點項目 ChartDB AI自動導表結構+遷移腳本,3分鐘生成專業數據庫關系圖

ChartDB堪稱數據庫設計神器!亮點①:動動手指輸入SQL,秒出結構圖,表關系一目了然,團隊評審時再也不用畫圖兩小時。亮點②:AI智能轉換超貼心,MySQL轉PostgreSQL只需點個按鈕,跨平臺遷移…

地質科研智能革命:當大語言模型“扎根”地質現場、大語言模型本地化部署與AI智能體協同創新實踐

在地質學邁向“深時數字地球”(Deep-time Digital Earth)的進程中,傳統研究方法正面臨海量異構數據(地質圖件、遙感影像、地震波譜等)的解析挑戰。大語言模型(LLM)與AI智能體的本地化部署技術&a…

DAPP實戰篇:使用web3.js連接合約

說明 本系列內容目錄:專欄:區塊鏈入門到放棄查看目錄 如果你還沒有創建好項目請先查看:《DApp實戰篇:先用前端起個項目》,如果你還不知道web3.js是什么請先查看:《DApp實戰篇:前端技術棧一覽》。 安裝 點此查看web3.js官方文檔 打開項目根目錄,并喚起終端: 鍵入w…

源代碼保密解決方案

背景分析 隨著各行各業業務數據信息化發展,各類產品研發及設計等行業,都有關乎自身發展的核心數據,包括業務數據、源代碼保密數據、機密文檔、用戶數據等敏感信息,這些信息數據有以下共性: — 屬于核心機密資料&…

dolphinscheduler單機部署鏈接oracle

部署成功請給小編一個贊或者收藏激勵小編 1、安裝準備 JDK版本:1.8或者1.8oracle版本:19Coracle驅動版本:8 2、安裝jdk 下載地址:https://www.oracle.com/java/technologies/downloads/#java8 下載后上傳到/tmp目錄下。 然后執行下面命…

2025-04-08 NO.4 Quest3 交互教程

文章目錄 1 環境準備2 新手指引:Building Blocks2.1 創建 OVR 相機2.2 創建交互功能2.3 創建交互物體 3 老手開發:Interaction SDK3.1 創建交互功能3.2 創建交互物體 4 UI 交互4.1 3D 按鈕4.2 Unity UI ? 新版 Meta SDK(v74)優化…

關于Spring MVC中@RequestMapping注解的詳細解析,涵蓋其核心功能、屬性、使用場景及最佳實踐

以下是關于Spring MVC中RequestMapping注解的詳細解析,涵蓋其核心功能、屬性、使用場景及最佳實踐: 1. 基礎概念 RequestMapping是Spring MVC的核心注解,用于將HTTP請求映射到控制器(Controller)的方法上。它支持類級…

Scala 異常處理

Scala 異常處理 引言 Scala 是一門多范式編程語言,它結合了面向對象和函數式編程的特性。在軟件開發過程中,異常處理是保證程序穩定性和可靠性的重要環節。本文將深入探討 Scala 中的異常處理機制,包括異常的拋出、捕獲和處理策略。 異常概述 什么是異常? 在計算機編程…

PyTorch:解鎖AI新時代的鑰匙

(前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到網站)。 揭開PyTorch面紗 對于許多剛開始接觸人工智能領域的朋友來說,PyTorch這個名字或許既熟悉又陌生。…

React-06React中refs屬性(字符串refs,回調形式,React.createRef() )

1.React中refs屬性 綁定到render輸出的任何組件上&#xff0c;通過this.ref.綁定名直接操作DOM元素或獲取子組件的實例。 2.綁定refs實例 2.1 字符串refs(已經過時參考官網API) 字符串(string)的ref存在一定的效率問題 <input refinput1 type"text" placehole…

五子棋游戲開發:靜態資源的重要性與設計思路

以下是以CSDN博客的形式整理的關于五子棋游戲靜態資源需求的文章&#xff0c;基于我們之前的討論&#xff0c;內容結構清晰&#xff0c;適合開發者閱讀和參考。我盡量保持技術性、實用性&#xff0c;同時加入一些吸引讀者的亮點。 五子棋游戲開發&#xff1a;靜態資源的重要性與…

c編譯和c++編譯有什么區別?

文章目錄 c編譯和c編譯有什么區別多態函數重載虛函數表 vtable 輸入輸出同步類型檢查模板和特化鏈接 C 標準庫 C 能編譯 C 的代碼嗎&#xff1f; c編譯和c編譯有什么區別 多態 函數重載 C 支持多個同名函數&#xff08;參數不同&#xff09;&#xff0c;這是編譯期多態 編譯…

無縫集成Docker與Maven:docker-maven-plugin實戰指南

關于 docker-maven-plugin 的詳細介紹和使用指南&#xff0c;幫助你在 Maven 項目中實現 Docker 鏡像的自動化構建、推送和管理。 1. 插件的作用 docker-maven-plugin 是一個 Maven 插件&#xff0c;允許在 Maven 構建生命周期中直接集成 Docker 操作&#xff0c;例如&#xf…

智能倉儲數字孿生Demo(Unity實現)

一、項目背景與行業痛點 醫藥流通行業倉儲管理面臨三大核心挑戰&#xff1a; 合規性風險&#xff1a;GSP&#xff08;藥品經營質量管理規范&#xff09;對溫濕度、藥品批次追溯的嚴苛要求&#xff0c;傳統人工記錄易出錯效率瓶頸&#xff1a;庫區布局復雜&#xff0c;人工巡檢…