遠程服務Service & AIDL & IPC

      網友投稿 709 2022-05-30

      為了讓遠程Service與多個應用程序的組件(四大組件)進行跨進程通信(IPC),需要使用AIDL

      IPC:Inter-Process Communication,即跨進程通信

      AIDL:Android Interface Definition Language,即Android接口定義語言;用于讓某個Service與多個應用程序組件之間進行跨進程通信,從而可以實現多個應用程序共享同一個Service的功能。

      遠程服務與本地服務不同點在于,它是運行在獨立進程中,常常向多個應用提供服務。

      那么其他應用應該如何與遠程服務通信呢?在Android中提供了AIDL的機制進行IPC進程間通信。

      創建遠程服務Service

      遠程服務Service,要通過以下步驟建立起來:

      步驟1:定義AIDL文件,并聲明提供服務的接口

      // IMyAidlInterface.aidl package com.ti.remoteservice; // Declare any non-default types here with import statements interface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); // AIDL中支持以下的數據類型 // 1. 基本數據類型 // 2. String 和CharSequence // 3. List 和 Map ,List和Map 對象的元素必須是AIDL支持的數據類型; // 4. AIDL自動生成的接口(需要導入-import) // 5. 實現android.os.Parcelable 接口的類(需要導入-import) void aidlService(); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      步驟2:在Service子類中實現AIDL中定義的接口方法,并定義生命周期的方法

      package com.ti.remoteservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class RemoteService extends Service { // 實例化AIDL的Stub類(Binder的子類) IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() { @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } @Override public void aidlService() throws RemoteException { Log.d("遠程服務##", "客戶端通過AIDL與遠程后臺成功通信"); } }; public RemoteService() { } // 重寫接口里定義的方法 @Override public void onCreate() { super.onCreate(); Log.d("遠程服務##", "onCeate創建服務"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("遠程服務##", "onStartCommand運行服務"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { Log.d("遠程服務##", "onBind綁定服務"); // 在onBind()返回繼承自Binder的Stub類型的Binder,非常重要 return mBinder; } @Override public boolean onUnbind(Intent intent) { Log.d("遠程服務##", "onUnbind解綁服務"); return super.onUnbind(intent); } @Override public void onDestroy() { Log.d("遠程服務##", "onDestroy銷毀服務"); super.onDestroy(); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      步驟3:在AndroidMainfest.xml中注冊服務,并且聲明為遠程服務

      ... android:process=":remote"> ...

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      遠程服務Service & AIDL & IPC

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      至此,遠程服務Service就已經完成了。

      遠程服務demo已上傳至Github,歡迎下載學習。

      要使用該遠程服務的應用要做的事

      步驟1:原封不動地(包名要有服務端的一樣)復制遠程服務Service端的AIDL文件到本應用對應的目錄下。(如果復制的AIDL文件所在的包路徑與服務端的不一樣,運行程序時就會崩潰)

      步驟2:使用Stub.asInterface接口獲取遠程服務的Binder,根據需要調用服務提供的接口方法。

      // 定義aidl接口變量 private IMyAidlInterface mAIDL_Service; //創建ServiceConnection的匿名類 private ServiceConnection connection = new ServiceConnection() { // 重寫onServiceConnected()方法和onServiceDisconnected()方法 // 在Activity與Service建立關聯和解除關聯的時候調用 @Override public void onServiceDisconnected(ComponentName name) { } //在Activity與Service建立關聯時調用 @Override public void onServiceConnected(ComponentName name, IBinder service) { //使用AIDLService1.Stub.asInterface()方法獲取服務器端返回的IBinder對象 //將IBinder對象傳換成了mAIDL_Service接口對象 mAIDL_Service = IMyAidlInterface.Stub.asInterface(service); try { // 通過該對象調用在MyAIDLService.aidl文件中定義的接口方法,從而實現跨進程通信 mAIDL_Service.aidlService(); } catch (RemoteException e) { e.printStackTrace(); } } };

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      步驟3:通過Intent指定遠程服務的服務名稱和所在的包,綁定遠程Service。

      // 通過Intent指定服務端的服務名稱和所在包,與遠程Service進行綁定 // 參數與服務器端的action要一致,即"服務器包名.aidl接口文件名" Intent intent = new Intent("com.ti.remoteservice.IMyAidlInterface"); // Android5.0后無法只通過隱式Intent綁定遠程Service // 需要通過setPackage()方法指定包名 intent.setPackage("com.ti.remoteservice"); // 綁定服務,傳入intent和ServiceConnection對象 bindService(intent, connection, Context.BIND_AUTO_CREATE);

      1

      2

      3

      4

      5

      6

      7

      8

      客戶端demo已上傳至Github,歡迎下載學習。

      謝謝閱讀。

      任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:華三vlan配置和 trunk實驗配置
      下一篇:2022CANN訓練營新手應用開發課學習筆記
      相關文章
      亚洲一本一道一区二区三区| 亚洲一区二区影院| 亚洲综合亚洲国产尤物| 国产91精品一区二区麻豆亚洲| 国产成人精品日本亚洲语音| 亚洲人成色777777老人头| 亚洲一卡2卡三卡4卡无卡下载| 亚洲大香伊人蕉在人依线| 亚洲欧洲日产专区| 亚洲的天堂av无码| 亚洲制服丝袜一区二区三区| 亚洲成aⅴ人片在线观| 亚洲欧洲日韩在线电影| 亚洲黄色在线电影| 亚洲欧洲日本国产| 亚洲 日韩经典 中文字幕 | 2017亚洲男人天堂一| 亚洲18在线天美| 亚洲自偷自偷在线成人网站传媒| 亚洲AV日韩综合一区尤物| 亚洲人成网站在线播放2019| 亚洲成av人无码亚洲成av人| 亚洲国产成人AV在线播放| 国产亚洲精品免费| 亚洲精品专区在线观看| 在线日韩日本国产亚洲| 国产亚洲一区二区手机在线观看| 亚洲AV无码一区东京热久久 | 亚洲国产三级在线观看| 亚洲电影中文字幕| 亚洲综合在线成人一区| 丁香婷婷亚洲六月综合色| 亚洲欧美日韩中文字幕一区二区三区 | 亚洲成a人片在线不卡| 中文字幕亚洲精品无码| 精品亚洲av无码一区二区柚蜜| 亚洲成A人片在线观看无码3D| 亚洲日本va午夜中文字幕久久| 亚洲日本一区二区三区在线| 亚洲图片在线观看| 亚洲一区二区三区久久久久|