Android bindservice綁定服務,并同步返回service對象的兩個方法

先上一段代碼:

private  IDeviceService deviceService = null;
private ServiceConnection conn=null;
private synchronized void bindyourservice() {    Intent intent = new Intent();intent.setPackage("servicepackagename");intent.setAction("serviceactionname");conn=new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {               deviceService = IDeviceService.Stub.asInterface(iBinder);}@Overridepublic void onServiceDisconnected(ComponentName componentName) {.....................................             }};try {if (bindService(intent, mConn, Service.BIND_AUTO_CREATE)) {...............................} else {....................}} catch (SecurityException e) {.........................}}

這個是最早綁定服務的方式,bindService返回綁定服務狀態,訪問服務接口需在取到ServiceConnection連接后再訪問,整個過程是異步的,而且就算開線程去綁定服務、加鎖也沒辦法在一個方法里面返回這個service對象,原因是這個方法里面的實現:

/frameworks/base/core/java/android/app/ContextImpl.java

看下這個的代碼:

  public boolean bindService(Intent service, ServiceConnection conn, int flags) {warnIfCallingFromSystemProcess();return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,getUser());}@Overridepublic boolean bindService(Intent service, int flags, Executor executor, ServiceConnection conn) {return bindServiceCommon(service, conn, flags, null, null, executor, getUser());}@Overridepublic boolean bindIsolatedService(Intent service, int flags, String instanceName,Executor executor, ServiceConnection conn) {warnIfCallingFromSystemProcess();if (instanceName == null) {throw new NullPointerException("null instanceName");}return bindServiceCommon(service, conn, flags, instanceName, null, executor, getUser());}@Overridepublic boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,UserHandle user) {return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, user);}/** @hide */@Overridepublic boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,Handler handler, UserHandle user) {if (handler == null) {throw new IllegalArgumentException("handler must not be null.");}return bindServiceCommon(service, conn, flags, null, handler, null, user);}.....................private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,String instanceName, Handler handler, Executor executor, UserHandle user) {....................
}

?bindServiceCommon是個私有方法,里面又套了幾層代碼,太長,翻起來就是整個系統bindservice的流程了。

關鍵點,bindservice執行的時候接收的Handler是?mMainThread.getHandler(),這個是APP的主線程,也就是無論外部怎么折騰,這個是在主線程接收的。

在上面這段系統代碼段里面,有兩個方法是可以使用的:

//method 1
public boolean bindService(Intent service, int flags, Executor executor, ServiceConnection conn)
//method 2
/** @hide */
@Override
public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,Handler handler, UserHandle user)

1、bindService

在bindService有一個傳參executor,接收ServiceConnection放到了這個里面:

private boolean[] isBind = {false};
private CountDownLatch latch = new CountDownLatch(1);
private boolean bindyourservice(final Context context){if(deviceService==null){latch = new CountDownLatch(1);Executor executor= Executors.newSingleThreadExecutor();executor.execute(new Runnable() {@Overridepublic void run() {mConn=new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName className, IBinderiBinder) {deviceService = IDeviceService.Stub.asInterface(iBinder);isBind[0] =true;latch.countDown();}@Overridepublic void onServiceDisconnected(ComponentName className) {                          isBind[0] =false;latch.countDown();}};Intent intent = new Intent();intent.setPackage("yourservicename");intent.setAction("yourserviceaction");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {boolean bind=bindService(intent, Context.BIND_AUTO_CREATE,executor,mConn);if(!bind){                               isBind[0] =false;latch.countDown();}}}});if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {                   try {latch.await();} catch (InterruptedException e) {e.printStackTrace();}                   if(!isBind[0])return false;}else{                   return false;}}         return true;}

需要注意的是Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q,這個方法是android7.0及以后提供的。

2、bindServiceAsUser

也可以實現方法1的功能,只不過把接收對象換成了Handler ,bindServiceAsUser是系統隱藏方法,需通過反射方法使用,至于bindServiceAsUser是否早于android7.0之前就有,無法確認。

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

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

相關文章

Go語言之空接口與類型斷言

Go 語言中,接口是一種強大的抽象機制。其中,空接口(interface{})和類型斷言為我們提供了處理任意類型與類型檢查的能力。 一、空接口(interface{}) 空接口是 Go 中最特殊的接口:不包含任何方法…

三、OrcaSlicer預設顯示

一、界面類 主框架使用的是wxWidgets庫;3D模型的渲染區的控件,使用的是imgui庫。 1、Plater 此類在OrcaSlicer\src\slic3r\GUI\Plater.hpp文件中定義 1.1 Plater::priv 此結構體是Plater的數據類,各種數據的對象和指針保存在此結構體中。如…

00 QEMU源碼中文注釋與架構講解

QEMU源碼中文注釋與架構講解 先占坑:等后續完善后再更新此文章 注釋作者將狼才鯨創建日期2025-05-30更新日期NULL CSDN閱讀地址:00 QEMU源碼中文注釋與架構講解Gitee源碼倉庫地址:才鯨嵌入式/qemu 一、前言 參考網址 QEMU 源碼目錄簡介qe…

一、Sqoop歷史發展及原理

作者:IvanCodes 日期:2025年5月30日 專欄:Sqoop教程 在大數據時代,數據往往分散存儲在各種不同類型的系統中。其中,傳統的關系型數據庫 (RDBMS) 如 MySQL, Oracle, PostgreSQL 等,仍然承載著大量的關鍵業務…

【Halcon】圖像分割中的 regiongrowing 與dyn_threshold 動態閾值 算法詳解對比

圖像分割中的 regiongrowing 與動態閾值算法詳解對比 在使用 HALCON 進行圖像處理時,圖像分割是最常見也最關鍵的操作之一。本文將深入講解 regiongrowing 算子的原理與使用方法,并與另一常見方法——動態閾值 (dyn_threshold) 進行詳細對比&#xff0c…

Docker部署項目無法訪問,登錄超時完整排查攻略

項目背景:遷移前后端應用,prod環境要求保留443端口,開發環境37800端口,后端容器端口為8000,前端為80,fastAPI對外端口為41000 生產環境部署在VM01,開發環境部署在VM03,在VM01配置nginx轉發 [r…

充電便捷,新能源汽車移動充電服務如何預約充電

隨著新能源汽車的普及,充電便捷性成為影響用戶體驗的關鍵因素之一。傳統的固定充電樁受限于地理位置和數量,難以完全滿足用戶需求,而移動充電服務的出現,為車主提供了更加靈活的補能方式。通過手機APP、小程序或在線平臺&#xff…

探索C++標準模板庫(STL):從容器到底層奧秘-全面解析String類高效技巧(上篇)

前引:在現代軟件開發中,字符串處理是幾乎所有程序的核心需求之一。無論是文本解析、網絡通信,還是用戶交互,高效且安全的字符串操作能力直接決定了代碼的質量與可維護性。而C標準模板庫(Standard Template Library, ST…

Python爬蟲實戰:抓取百度15天天氣預報數據

🌐 編程基礎第一期《9-30》–使用python中的第三方模塊requests,和三個內置模塊(re、json、pprint),實現百度地圖的近15天天氣信息抓取 記得安裝 pip install requests📑 項目介紹 網絡爬蟲是Python最受歡迎的應用場景之一&…

HTML常見事件詳解:從入門到實戰應用

前言 在Web開發中,事件是用戶與網頁交互的核心機制。HTML事件讓我們能夠響應用戶的各種操作,如點擊、鼠標移動、鍵盤輸入等。掌握HTML事件是前端開發的基礎技能之一,本文將深入探討HTML中的常見事件類型及其實際應用。 HTML事件概覽總結 H…

模具制造業數字化轉型:精密模塑,以數字之力鑄就制造基石

模具被譽為 “工業之母”,是制造業的重要基石,其精度直接決定了工業產品的質量與性能。在工業制造向高精度、智能化發展的當下,《模具制造業數字化轉型:精密模塑,以數字之力鑄就制造基石》這一主題,精準點明…

深度解讀漏洞掃描:原理、類型與應用實踐

在網絡安全領域,漏洞就像隱藏在系統中的定時炸彈,隨時可能被攻擊者利用,導致數據泄露、服務癱瘓等嚴重后果。而漏洞掃描作為發現這些潛在威脅的 “偵察兵”,是保障網絡安全的重要防線。本文將全面介紹漏洞掃描的相關知識&#xff…

[HNCTF 2022 Week1]silly_zip

下載附件 解壓發現需要密碼 用010打開看看,發現是偽加密 改成00點擊保存 解壓后得到圖片 感覺圖片看著怪怪的,修改一下高度看看有沒有其他線索 把47改成78 最后得到flag

Facebook 的隱私保護措施是否足夠?技術觀點

在數字時代,隱私保護成為了公眾關注的焦點,尤其是對于擁有數十億用戶的社交媒體巨頭 Facebook 來說,其隱私保護措施的有效性更是備受矚目。本文將從技術角度探討 Facebook 的隱私保護措施是否足夠。 數據收集與使用 Facebook 收集用戶數據的…

cocosCreator 1.8 升級到 2.4

現在負責的一個運營中的商業項目,使用的是 cocosCreator1.8,之前沒有做好設計,所以東西都是直接加載在內存中的,到了現在性能問題逐漸暴露出來,討論之后想進行引擎升級,升級到cocosCreator 2.4。 官方的升…

ubuntu 制作 ssl 證書

安裝 openssl sudo apt install openssl 生成 SSL 證書 # 生成私鑰 (Private Key) openssl genrsa -out private.key 2048 在當前目錄生成 private.key # 生成證書簽名請求 (CSR - Certificate Signing Request) openssl req -new -key private.key -out certificate.csr -…

【Java基礎-環境搭建-創建項目】IntelliJ IDEA創建Java項目的詳細步驟

在Java開發的世界里,選擇一個強大的集成開發環境(IDE)是邁向高效編程的第一步。而IntelliJ IDEA無疑是Java開發者中最受歡迎的選擇之一。它以其強大的功能、智能的代碼輔助和簡潔的用戶界面,幫助無數開發者快速構建和部署Java項目…

WEB3——什么是ABI

怎么獲得ABI? 在編譯完合約后,可以在左邊下面點擊復制ABI ABI(Application Binary Interface,應用二進制接口)是用來讓前端或服務端 JavaScript 代碼與智能合約進行交互的橋梁,它描述了合約的函數、事件和…

移動安全Android——客戶端數據安全

本地文件權限配置 測試流程 (1)手機運行待測APP應用,adb執行命令找到APP包名 adb shell dumpsys activity top|findstr ACTIVITY (2)adb shell 進入設備,以Root權限進入/data/data/package包名目錄下 c…

拉普拉斯噪聲

1. 概念 拉普拉斯噪聲是一種連續概率分布生成的隨機噪聲,其核心特點是符合拉普拉斯分布。這種噪聲被特意添加到數據(尤其是查詢結果或統計量)中,以實現差分隱私這一嚴格的隱私保護框架。 核心目的: 在保護數據集中的個…