Android 深入淺出AIDL(一)

前言

本文主要講述AIDL作用以及如何快速上手AIDL項(xiàng)目

簡介

A [android]
I [Interface]
D [Definition]
L [Language]
Android接口定義語言叫确。
作用:方便系統(tǒng)為我們生成代碼從而實(shí)現(xiàn)跨進(jìn)程通訊七扰,僅此而已猎贴。(玉剛老師如是說也)键痛,也就是說這個(gè)AIDL就只是一個(gè)快速跨進(jìn)程通訊的工具励稳。

快速上手

本篇文章意在快速實(shí)現(xiàn)AIDL項(xiàng)目,更多詳細(xì)內(nèi)容下篇繼續(xù)闡述。

在服務(wù)端創(chuàng)建AIDL文件降宅,用來聲明java Bean以及傳輸調(diào)用的接口∏舭裕【聲明文件】
在服務(wù)端創(chuàng)建Service并且實(shí)現(xiàn)上面的接口腰根。【創(chuàng)建服務(wù)】
客戶端綁定Service拓型《詈伲【綁定服務(wù)】
客戶端調(diào)用服務(wù)端接口×哟欤【跨進(jìn)程調(diào)用】

服務(wù)端

創(chuàng)建服務(wù)端項(xiàng)目
首先我們在app/src/main 目錄下創(chuàng)建AIDL文件夾册养。


image.png

創(chuàng)建載體MessageBean

首先我們在這個(gè)AIDL文件夾里創(chuàng)建用來傳輸?shù)膉ava Bean對象(包名并不重要),并且實(shí)現(xiàn)Parcelable接口(建議使用Parcelable插件)压固,因?yàn)檫M(jìn)程間通訊需要將該對象轉(zhuǎn)化為字節(jié)序列球拦,用于傳輸或者存儲(chǔ)。(傳遞的載體)

public class MessageBean implements Parcelable {
private String content;//需求內(nèi)容
private int level;//重要等級(jí)

``````
get set方法
``````

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.content);
    dest.writeInt(this.level);
}

//如果需要支持定向tag為out,inout邓夕,就要重寫該方法
public void readFromParcel(Parcel dest) {
    //注意刘莹,此處的讀值順序應(yīng)當(dāng)是和writeToParcel()方法中一致的
    this.content = dest.readString();
    this.level = dest.readInt();
}
protected MessageBean(Parcel in) {
    this.content = in.readString();
    this.level = in.readInt();
}
public MessageBean() {

public static final Creator<MessageBean> CREATOR = new Creator<MessageBean>() {
    @Override
    public MessageBean createFromParcel(Parcel source) {
        return new MessageBean(source);
    }

    @Override
    public MessageBean[] newArray(int size) {
        return new MessageBean[size];
    }
};
}

創(chuàng)建AIDL文件MessageBean.AIDL

因?yàn)锳IDL這個(gè)語言的規(guī)范就是aidl文件阎毅,所以我們必須將MessageBean轉(zhuǎn)為aidl文件焚刚,供其它aidl的調(diào)用與交互。就這么簡單扇调,一個(gè)文件里面兩行代碼矿咕。(這個(gè)文件要與java Bean放置同一包下)

package qdx.aidlserver;//手動(dòng)導(dǎo)包
parcelable MessageBean;//parcelable是小寫

AIDL文件與java文件的區(qū)別

文件類型:用AIDL書寫的文件的后綴是 .aidl,而不是 .java狼钮。
數(shù)據(jù)類型:AIDL默認(rèn)支持一些數(shù)據(jù)類型碳柱,在使用這些數(shù)據(jù)類型的時(shí)候是不需要導(dǎo)包的,但是除了這些類型之外的數(shù)據(jù)類型熬芜,在使用之前必須導(dǎo)包莲镣,就算目標(biāo)文件與當(dāng)前正在編寫的 .aidl 文件在同一個(gè)包下——在 Java 中,這種情況是不需要導(dǎo)包的涎拉。比如瑞侮,現(xiàn)在我們編寫了兩個(gè)文件,一個(gè)叫做 IDemandManager.java 鼓拧,另一個(gè)叫做 IDemandManager.aidl半火,它們都在 qdx.aidlserver 包下 ,現(xiàn)在我們需要在 .aidl 文件里使用 MessageBean 對象季俩,那么我們就必須在 .aidl 文件里面寫上 import qdx.aidlserver.MessageBean; 哪怕 .java 文件和 .aidl 文件就在一個(gè)包下钮糖。

默認(rèn)支持的數(shù)據(jù)類型
Java中的八種基本數(shù)據(jù)類型( byte,short(不支持short酌住,編譯不通過)店归,int阎抒,long,float娱节,double挠蛉,boolean,char)
String 和 CharSequence類型
List : List中的所有元素必須是AIDL支持的類型之一肄满,里面的每個(gè)元素都必須能夠被AIDL支持
Map : Map中的所有元素必須是AIDL支持的類型之一谴古,包括key和value
Parcelabel : 所有實(shí)現(xiàn)了Parcelabel 接口的對象
AILD : 所有的AIDL接口本身也可以在AIDL文件中使用

創(chuàng)建AIDL文件IDemandManager.AIDL

我們創(chuàng)建IDemandManager接口用來實(shí)現(xiàn)傳遞方法。
另外方法內(nèi)如果有傳輸載體稠歉,就必須指明定向tag(in,out,inout)

  • in : 客戶端數(shù)據(jù)對象流向服務(wù)端掰担,并且服務(wù)端對該數(shù)據(jù)對象的修改不會(huì)影響到客戶端。

  • out : 數(shù)據(jù)對象由服務(wù)端流向客戶端怒炸,(客戶端傳遞的數(shù)據(jù)對象此時(shí)服務(wù)端收到的對象內(nèi)容為空带饱,服務(wù)端可以對該數(shù)據(jù)對象修改,并傳給客戶端)

  • inout : 以上兩種數(shù)據(jù)流向的結(jié)合體阅羹。(但是不建議用此tag,會(huì)增加開銷)

    package qdx.aidlserver;
    
    import qdx.aidlserver.MessageBean;
     import qdx.aidlserver.IDemandListener;
    
    interface IDemandManager {
    MessageBean getDemand();
    
     void setDemandIn(in MessageBean msg);//客戶端->服務(wù)端
    
     //out和inout都需要重寫MessageBean的readFromParcel方法
     void setDemandOut(out MessageBean msg);//服務(wù)端->客戶端
    
    void setDemandInOut(inout MessageBean msg);//客戶端<->服務(wù)端
    }
    

埋坑與完善

該篇文章內(nèi)容不多勺疼,但是處處皆是精華,尤其是以下3條建議捏鱼,以防引起慘案执庐。

  1. xxx.aidl 中不能存在同方法名不同參數(shù)的方法。

  2. xxx.aidl 中實(shí)體類必須要有指定的tag导梆。

  3. 在Android Studio里寫完aidl文件還需要在build.gradle文件中android{}方法內(nèi)添加aidl路徑轨淌。

    sourceSets {
     main {
      java.srcDirs = ['src/main/java', 'src/main/aidl']
      }
     }
    

創(chuàng)建Service

最后我們還需要?jiǎng)?chuàng)建一個(gè)服務(wù),用來處理客戶端發(fā)來的請求看尼,或者是定時(shí)推信息到客戶端递鹉。

public class AIDLService extends Service {

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

//Stub內(nèi)部繼承Binder,具有跨進(jìn)程傳輸能力
IDemandManager.Stub demandManager = new IDemandManager.Stub() {
    @Override
    public MessageBean getDemand() throws RemoteException {
        MessageBean demand = new MessageBean("首先藏斩,看到我要敬禮", 1);
        return demand;
    }

    @Override
    public void setDemandIn(MessageBean msg) throws RemoteException {//客戶端數(shù)據(jù)流向服務(wù)端
        Log.i(TAG, "程序員:" + msg.toString());
    }

    @Override
    public void setDemandOut(MessageBean msg) throws RemoteException {//服務(wù)端數(shù)據(jù)流向客戶端
        Log.i(TAG, "程序員:" + msg.toString());//msg內(nèi)容一定為空

        msg.setContent("我不想聽解釋躏结,下班前把所有工作都搞好!");
        msg.setLevel(5);
    }

    @Override
    public void setDemandInOut(MessageBean msg) throws RemoteException {//數(shù)據(jù)互通
        Log.i(TAG, "程序員:" + msg.toString());

        msg.setContent("把用戶交互顏色都改成粉色");
        msg.setLevel(3);
    }
};

}
最后我們在清單文件中注冊服務(wù)
action 為服務(wù)名稱狰域,客戶端可以通過此(com.tengxun.aidl)隱式啟動(dòng)該服務(wù)媳拴。
在魅族的手機(jī)上,系統(tǒng)禁止了隱式方法啟動(dòng)服務(wù)的權(quán)限北专,所以務(wù)必在手機(jī)管家/權(quán)限管理/ 中禀挫,開啟該項(xiàng)目的自啟權(quán)限。
<service
android:name=".AIDLService"
android:exported="true">
<intent-filter>
<action android:name="com.tengxun.aidl" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拓颓,一起剝皮案震驚了整個(gè)濱河市语婴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖砰左,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匿醒,死亡現(xiàn)場離奇詭異,居然都是意外死亡缠导,警方通過查閱死者的電腦和手機(jī)廉羔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來僻造,“玉大人憋他,你說我怎么就攤上這事∷柘鳎” “怎么了竹挡?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長立膛。 經(jīng)常有香客問我揪罕,道長,這世上最難降的妖魔是什么宝泵? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任好啰,我火速辦了婚禮,結(jié)果婚禮上儿奶,老公的妹妹穿的比我還像新娘框往。我一直安慰自己,他們只是感情好廓握,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布搅窿。 她就那樣靜靜地躺著嘁酿,像睡著了一般隙券。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上闹司,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天娱仔,我揣著相機(jī)與錄音,去河邊找鬼游桩。 笑死牲迫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的借卧。 我是一名探鬼主播盹憎,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼铐刘!你這毒婦竟也來了陪每?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎檩禾,沒想到半個(gè)月后挂签,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盼产,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年饵婆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片戏售。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侨核,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出灌灾,到底是詐尸還是另有隱情芹关,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布紧卒,位于F島的核電站侥衬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏跑芳。R本人自食惡果不足惜轴总,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望博个。 院中可真熱鬧怀樟,春花似錦、人聲如沸盆佣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽共耍。三九已至虑灰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痹兜,已是汗流浹背穆咐。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留字旭,地道東北人对湃。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像遗淳,于是被迫代替她去往敵國和親拍柒。 傳聞我的和親對象是個(gè)殘疾皇子己莺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容