日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android IPC系列(一):AIDL使用详解

發布時間:2023/12/2 Android 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android IPC系列(一):AIDL使用详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

AIDL可以實現進程間的通信,由于每個進程都是運行在獨立的空間,不同的進程想要交互需要借助一些特殊的方式,AIDL就是其中的一種,AIDL是一種模板,因為實際交互過程中,并不是AIDL起的作用,具體會在之后源碼分析解釋,AIDL的作用是為了避免重復編寫代碼而出現的一個模板

語法

AIDL的語法十分簡單,與Java語言基本保持一致,需要記住的規則有以下幾點:

  • AIDL文件以 .aidl 為后綴名 AIDL支持的數據類型分為如下幾種:

    • 八種基本數據類型:byte、char、int、long、float、double、boolean String,CharSequence,其中不支持short類型
    • 實現了Parcelable接口的數據類型
    • List 類型。List承載的數據必須是AIDL支持的類型,或者是其它聲明的AIDL對象
    • Map類型。Map承載的數據必須是AIDL支持的類型,或者是其它聲明的AIDL對象
  • 定向Tag。定向Tag表示在跨進程通信中數據的流向,用于標注方法的參數值,分為 in、out、inout 三種。其中

    • in 表示數據只能由客戶端流向服務端
    • out 表示數據只能由服務端流向客戶端
    • inout 則表示數據可在服務端與客戶端之間雙向流通
    • 此外,如果AIDL方法接口的參數值類型是:基本數據類型、String、CharSequence或者其他AIDL文件定義的方法接口,那么這些參數值的定向 Tag 默認是且只能是 in,所以除了這些類型外,其他參數值都需要明確標注使用哪種定向Tag。定向Tag具體的使用差別后邊會有介紹
  • 明確導包。在AIDL文件中需要明確標明引用到的數據類型所在的包名,即使兩個文件處在同個包名下

服務端

  • 先建立一個項目
  • 由于要傳輸自定義User對象,所以定義一個User的aidl文件,直接生成 創建完成后,系統就會默認創建一個 aidl 文件夾,文件夾下的目錄結構即是工程的包名,Book.aidi 文件就在其中 然后更改User.aidl文件內容
package com.baidu.bpit.aibaidu.aidl;parcelable User; 復制代碼
  • 然后生成一個User的類,實現Parcelable
public class User implements Parcelable {public String name;public User(String name){this.name=name;}protected User(Parcel in) {name = in.readString();}public static final Creator<User> CREATOR = new Creator<User>() {@Overridepublic User createFromParcel(Parcel in) {return new User(in);}@Overridepublic User[] newArray(int size) {return new User[size];}};@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(name);} } 復制代碼
  • 然后在定義一個BookName的aidl文件,向客戶端暴露可調用的接口,需要手動導入User,import com.baidu.bpit.aibaidu.aidl.User;
package com.baidu.bpit.aibaidu.aidl; import com.baidu.bpit.aibaidu.aidl.User; interface BookName {String getName();List<User> getList();} 復制代碼
  • 這時候重新build一下工程
  • 現在需要來創建一個 Service 供客戶端遠程綁定了,返回你的自定義的Binder
public class ServiceService extends Service {public ServiceService() {}@Overridepublic IBinder onBind(Intent intent) {return new MyBinder();}class MyBinder extends BookName.Stub {@Overridepublic String getName() throws RemoteException {return "西游記";}@Overridepublic List<User> getList() throws RemoteException {User user = new User("111");User user1 = new User("222");List<User> users = new ArrayList<>();users.add(user1);users.add(user);return users;}} } 復制代碼
  • AndroidManifest.xml文件定義
<serviceandroid:name=".ServiceService"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.aaa.aaa" /></intent-filter></service> 復制代碼

客戶端

  • 首先把服務端的aidl文件夾,整體復制到客戶端
  • 之后,需要創建和服務端User類所在的相同包名來存放 User類
  • 在MainActivity綁定服務端的service,點擊按鈕獲取書名
public class MainActivity extends AppCompatActivity {private BookName bookName;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bindServer();initView();}private void initView() {findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {Log.d("mmmgetName", bookName.getName());List<User> list = bookName.getList();for (User user : list) {Log.d("mmmgetList", user.name);}} catch (RemoteException e) {e.printStackTrace();}}});}private void bindServer() {Intent mIntent = new Intent();//你定義的service的actionmIntent.setAction("com.aaa.aaa");//這里你需要設置你應用的包名mIntent.setPackage("com.baidu.bpit.aibaidu.aidl");bindService(mIntent, new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {bookName = BookName.Stub.asInterface(service);}@Overridepublic void onServiceDisconnected(ComponentName name) {}}, BIND_AUTO_CREATE);} }復制代碼
  • 點擊按鈕打印
01-18 22:11:17.642 4542-4542/com.baidu.bpit.aibaidu.client D/mmmgetName: 西游記 01-18 22:11:17.643 4542-4542/com.baidu.bpit.aibaidu.client D/mmmgetList: 222111 復制代碼

正確獲取數據

定向TAG

有三種定向TAG

  • inout:服務端修改數據,會同步到客戶端,因此可以說數據是雙向流動的
  • in:數據只從客戶端流向服務端,服務端修改數據不會影響客戶端
  • out:數據只能由服務端傳向客戶端,及時客戶端傳入一個對象,這個對象也是空的,即沒有數據,服務端獲取該對象后,對該對象任何操作都會同步到客戶端這里

修改aidl

interface BookName {String getName();List<User> getList();void addInout(inout User user);void addIn(in User user);void addout(out User user);} 復制代碼

這次增加了三個方法addInout,addIn,addout,之后分別測試這三個方法

修改User類 User類需要添加倆個方法,一個無參構造,一個readFromParcel

public class User implements Parcelable {public String name;public User(){}public User(String name){this.name=name;}protected User(Parcel in) {name = in.readString();}public static final Creator<User> CREATOR = new Creator<User>() {@Overridepublic User createFromParcel(Parcel in) {return new User(in);}@Overridepublic User[] newArray(int size) {return new User[size];}};@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(name);}public void readFromParcel(Parcel dest) {name = dest.readString();} } 復制代碼

先測試一下inout

服務端

public class ServiceService extends Service {public ServiceService() {}@Overridepublic IBinder onBind(Intent intent) {return new MyBinder();}class MyBinder extends BookName.Stub {@Overridepublic String getName() throws RemoteException {return "西游記";}@Overridepublic List<User> getList() throws RemoteException {User user = new User("111");User user1 = new User("222");List<User> users = new ArrayList<>();users.add(user1);users.add(user);return users;}@Overridepublic void addInout(User user) throws RemoteException {Log.d("mmmserver","服務端獲取到:"+user.name);user.name="服務端更改";Log.d("mmmserver","服務端修改書名:"+user.name);}@Overridepublic void addIn(User user) throws RemoteException {}@Overridepublic void addout(User user) throws RemoteException {}} } 復制代碼

主要看inout方法,服務端接受到客戶端傳來的信息后,修改信息內容

客戶端

private void initView() {findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {User user = new User("客戶端傳入");Log.d("mmmclient", "客戶端向服務端傳入一本書,書名:" + user.name);bookName.addInout(user);Log.d("mmmclient", "服務端修改書名后,書名:" + user.name);} catch (RemoteException e) {e.printStackTrace();}}});} 復制代碼

點擊按鈕后,向服務端傳入數據,服務端收到數據,會對數據更改,客戶端再次查看此數據,看是否同步

01-18 23:15:18.529 5606-5606/com.baidu.bpit.aibaidu.client D/mmmclient: 客戶端向服務端傳入一本書,書名:客戶端傳入 01-18 23:15:18.529 5527-5554/com.baidu.bpit.aibaidu.aidl D/mmmserver: 服務端獲取到:客戶端傳入 01-18 23:15:18.530 5527-5554/com.baidu.bpit.aibaidu.aidl D/mmmserver: 服務端修改書名:服務端更改 01-18 23:15:18.530 5606-5606/com.baidu.bpit.aibaidu.client D/mmmclient: 服務端修改書名后,書名:服務端更改 復制代碼

看到服務端修改可以及時同步到客戶端,這就是inout 數據雙向流動

測試in

服務端

@Overridepublic void addIn(User user) throws RemoteException {Log.d("mmmserverIn", "服務端獲取到:" + user.name);user.name = "服務端更改";Log.d("mmmserverIn", "服務端修改書名:" + user.name);} 復制代碼

客戶端

private void initView() {findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {User user = new User("客戶端傳入");Log.d("mmmclient", "客戶端向服務端傳入一本書,書名:" + user.name);bookName.addIn(user);Log.d("mmmclient", "服務端修改書名后,書名:" + user.name);} catch (RemoteException e) {e.printStackTrace();}}});} 復制代碼

當點擊按鈕,會發送數據到服務端,服務端會更改數據內容,客戶端再次查看數據,看是否被改變

01-18 23:26:23.079 5815-5815/com.baidu.bpit.aibaidu.client D/mmmclient: 客戶端向服務端傳入一本書,書名:客戶端傳入 01-18 23:26:23.080 5736-5763/com.baidu.bpit.aibaidu.aidl D/mmmserverIn: 服務端獲取到:客戶端傳入 01-18 23:26:23.081 5736-5763/com.baidu.bpit.aibaidu.aidl D/mmmserverIn: 服務端修改書名:服務端更改 01-18 23:26:23.081 5815-5815/com.baidu.bpit.aibaidu.client D/mmmclient: 服務端修改書名后,書名:客戶端傳入 復制代碼

看以看出服務端修改數據,并不會影響客戶端

測試OUT

服務端

@Overridepublic void addout(User user) throws RemoteException {Log.d("mmmserverout", "服務端獲取到:" + user.name);user.name = "服務端更改";Log.d("mmmserverout", "服務端修改書名:" + user.name);} 復制代碼

客戶端

private void initView() {findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {User user = new User("客戶端傳入");Log.d("mmmclient", "客戶端向服務端傳入一本書,書名:" + user.name);bookName.addout(user);Log.d("mmmclient", "服務端修改書名后,書名:" + user.name);} catch (RemoteException e) {e.printStackTrace();}}});} 復制代碼

客戶端向服務端傳入數據,服務端收到后,更改數據,客戶端再次查看數據

01-18 23:36:21.997 6100-6100/com.baidu.bpit.aibaidu.client D/mmmclient: 客戶端向服務端傳入一本書,書名:客戶端傳入 01-18 23:36:21.998 6023-6037/com.baidu.bpit.aibaidu.aidl D/mmmserverout: 服務端獲取到:null服務端修改書名:服務端更改 01-18 23:36:21.998 6100-6100/com.baidu.bpit.aibaidu.client D/mmmclient: 服務端修改書名后,書名:服務端更改 復制代碼

可以看到服務端收到的是空對象,服務端更改影響客戶端

GitHub: 參考:www.jianshu.com/p/29999c1a9…

轉載于:https://juejin.im/post/5d4d12e7518825237b5bdb4d

總結

以上是生活随笔為你收集整理的Android IPC系列(一):AIDL使用详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 男女一起插插插 | 日韩午夜在线视频 | 麻豆一级片 | 国产97免费视频 | 秋霞网一区 | 九九在线视频 | 亚洲自拍偷拍精品视频 | 免费av影片 | 软萌小仙自慰喷白浆 | 国产精品美女www爽爽爽 | 一级成人毛片 | 人妻 日韩 欧美 综合 制服 | 青娱乐91| 亚欧三级 | 成人性生交大片免费 | zzjj国产精品一区二区 | 国产高潮失禁喷水爽到抽搐 | 九七人人爽| 成人手机看片 | 国语精品| 天天操操夜夜操操 | 黄色中文| 国产91精品一区二区 | 福利免费观看 | 久久机热这里只有精品 | 97在线看 | 国产精品666| 亚洲免费人成 | 一个人免费在线观看视频 | 日韩精品二区在线观看 | 极品白嫩少妇无套内谢 | jizz一区二区 | 国产精品一级视频 | 少妇饥渴难耐 | 日本精品入口免费视频 | 成人特级毛片69免费观看 | 手机在线观看av | 伊人99热 | 国产免费黄色录像 | 肌肉猛男裸体gay网站免费 | 羞羞免费视频 | 亚洲精品在线播放视频 | 看av网址| 国产第一毛片 | 五月天激情婷婷 | www.日韩| 亚洲一区二区三区免费在线观看 | 久久五月视频 | 亚洲精品乱码久久久久久蜜桃麻豆 | 久久网页 | 欧美性视频网站 | aaaa黄色片 | 国产资源站 | 久久久久久影院 | 伊人日日夜夜 | 国产精品中文字幕在线 | 精品国产乱码久久久久久婷婷 | 午夜免费体验区 | 国产精品日韩专区 | 国产在线1区 | 国产aⅴ片 | 色欲久久久天天天综合网精品 | 天堂精品一区 | 午夜性福利视频 | 国产一区欧美二区 | 69社| 国产又爽又黄免费视频 | 日韩少妇诱惑 | 亚洲av色一区二区三区精品 | 日韩精品在线观看一区二区 | 欧美日韩精品久久久 | 在线午夜视频 | 久久国产加勒比精品无码 | 一区二区免费在线观看视频 | 亚洲综合不卡 | 日本爽妇网 | 亚洲成人激情av | 国产成人8x视频一区二区 | 成人精品一区二区三区中文字幕 | 天堂av在线网 | 国产乱人乱偷精品视频 | youjizz中国少妇| 精品久久网站 | 99ri在线观看 | 亲嘴扒胸摸屁股激烈网站 | 国产福利一区二区三区 | 中文字幕无码精品亚洲35 | 借种(出轨高h) | 玉足调教丨vk24分钟 | 国产又大又粗又硬 | www.精品视频 | 高清精品xnxxcom| 风间由美一区 | 潘金莲激情呻吟欲求不满视频 | av电影一区二区 | 亚洲综合色站 | 亚洲精品无码一区二区 | 美女野外找人搭讪啪啪 | 伊人导航 |