日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > 綜合技術(shù) > AIDL簡單使用

AIDL簡單使用

來源:程序員人生   發(fā)布時(shí)間:2016-11-20 16:41:28 閱讀次數(shù):3340次

AIDL是Android Interface Definition Language, 顧名思義,它主要就是用來定義接口的1種語言。Android提供AIDL主要用來進(jìn)程間通訊。

AIDL的功能來看,它主要的利用場景就是IPC。雖然同1個(gè)進(jìn)程中的client-service也能夠通過AIDL定義接口來進(jìn)行通訊,但這并沒有發(fā)揮AIDL的主要功能。 概括來講:

  1. 如果不需要IPC,那就直接實(shí)現(xiàn)通過繼承Binder類來實(shí)現(xiàn)客戶端和服務(wù)端之間的通訊。
  2. 如果確切需要IPC,但是無需處理多線程,那末就應(yīng)當(dāng)通過Messenger來實(shí)現(xiàn)。Messenger保證了消息是串行處理的,其內(nèi)部其實(shí)也是通過AIDL來實(shí)現(xiàn)。
  3. 在有IPC需求,同時(shí)服務(wù)端需要并發(fā)處理多個(gè)要求的時(shí)候,使用AIDL才是必要的

AIDL的簡單使用步驟以下:

  1. 編寫.AIDL文件,定義需要的接口
  2. 實(shí)現(xiàn)定義的接口
  3. 將接口暴露給客戶端調(diào)用

下面在AS上創(chuàng)建1個(gè)工程來使用1下:

創(chuàng)建Aidl文件:

創(chuàng)建完后,可以看到aidl接口文件里面已為我們提供了案例:

// IMyAidlInterface.aidl package com.example.aidltest; // 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支持以下所述的數(shù)據(jù)類型:

  • 所有的基本類型(int、float等)
  • String
  • CharSequence
  • List
  • Map

如果要使用自定義的類型,必須實(shí)現(xiàn)Parcelable接口才能進(jìn)行進(jìn)程間通訊。

下面自定義HelloMsg類:

public class HelloMsg implements Parcelable { private String name; private int age; public HelloMsg(String name, int age) { this.name = name; this.age = age; } protected HelloMsg(Parcel in) { name = in.readString(); age = in.readInt(); } public static final Creator<HelloMsg> CREATOR = new Creator<HelloMsg>() { @Override public HelloMsg createFromParcel(Parcel in) { return new HelloMsg(in); } @Override public HelloMsg[] newArray(int size) { return new HelloMsg[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); } @Override public String toString() { return "HelloMsg{" + "name='" + name + '\'' + ", age=" + age + '}'; } }

定義好HelloMsg.java以后,還需要新增1個(gè)與其對(duì)應(yīng)的AIDL文件。那末一樣依照剛才的步驟右鍵src文件夾,添加1個(gè)名為IHelloMsgInterface的AIDL文件。

// IHelloMsgInterface.aidl package com.example.aidltest; parcelable HelloMsg;

注意到parcelable的首字母是小寫的,這算是AIDL1個(gè)特殊的地方。
接下來還需要修改IMyAidlInterface.aidl文件,以下:

// IMyAidlInterface.aidl package com.example.aidltest; import com.example.aidltest.HelloMsg; interface IMyAidlInterface { HelloMsg sayHello(); }


 即使IMyAidlInterface.aidl和IHelloMsgInterface.aidl位于同1個(gè)包下,這里的import是必須要有的。這也是AIDL1個(gè)特殊的地方。


 注意:build以后發(fā)現(xiàn)會(huì)報(bào)錯(cuò),將IHelloMsgInterfece.aidl重命名為HelloMsg.aidl便可。


build成功以后會(huì)在build/generated/souce/aidl/debug目錄下生成IMyAidlInterface文件。可以大致熟習(xí)下該文件的內(nèi)容,對(duì)掌握android binder機(jī)制很有幫助

public interface IMyAidlInterface extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.example.aidltest.IMyAidlInterface { private static final java.lang.String DESCRIPTOR = "com.example.aidltest.IMyAidlInterface"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.example.aidltest.IMyAidlInterface interface, * generating a proxy if needed. */ public static com.example.aidltest.IMyAidlInterface asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof com.example.aidltest.IMyAidlInterface))) { return ((com.example.aidltest.IMyAidlInterface)iin); } return new com.example.aidltest.IMyAidlInterface.Stub.Proxy(obj); }


這里有個(gè)內(nèi)部類Stub,它繼承系統(tǒng)Binder類和實(shí)現(xiàn)IMyAidlInterface接口。另外還提供了asInterface()接口,這個(gè)方法接受1個(gè)遠(yuǎn)端Binder對(duì)象,并將其轉(zhuǎn)化成Stub對(duì)應(yīng)的接口對(duì)象并返回。在構(gòu)造方法調(diào)用Binder中的attachInterface方法把當(dāng)前服務(wù)對(duì)象和描寫符進(jìn)行關(guān)聯(lián)。在asInterface方法中會(huì)調(diào)用queryLocalInterface查詢,如果不在同1進(jìn)程就返回null,這個(gè)時(shí)候就返回Proxy對(duì)象。

上面看完了Stub類以后,發(fā)現(xiàn)他實(shí)際上是遠(yuǎn)端服務(wù)Binder對(duì)象的1個(gè)中間者,用來和客戶端進(jìn)行交互的,下面再來看1下Proxy類:

private static class Proxy implements com.example.aidltest.IMyAidlInterface { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(anInt); _data.writeLong(aLong); _data.writeInt(((aBoolean)?(1):(0))); _data.writeFloat(aFloat); _data.writeDouble(aDouble); _data.writeString(aString); mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public com.example.aidltest.HelloMsg sayHello() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); com.example.aidltest.HelloMsg _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_sayHello, _data, _reply, 0); _reply.readException(); if ((0!=_reply.readInt())) { _result = com.example.aidltest.HelloMsg.CREATOR.createFromParcel(_reply); }

可以看到里面有個(gè)mRemote對(duì)象,它是服務(wù)端傳遞過來的binder對(duì)象。調(diào)用transact方法后會(huì)調(diào)用上面Stub中的onTransact方法。這里其實(shí)用了靜態(tài)代理模式,Proxy就是遠(yuǎn)端傳遞過來的binder的本地代理。可以理解為客戶真?zhèn)€中間者。

Stub類是服務(wù)真?zhèn)€中間者,1般是實(shí)現(xiàn)了AIDL接口類型和繼承了Binder類,具有將Binder對(duì)象轉(zhuǎn)化成原生對(duì)象的能力
Proxy類是客戶真?zhèn)€中間者,1般是實(shí)現(xiàn)了AIDL接口類型

下面實(shí)現(xiàn)服務(wù)真?zhèn)€接口,定義RemoteService.java

public class RemoteService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return new IMyAidlInterface.Stub() { @Override public HelloMsg sayHello() throws RemoteException { return new HelloMsg("wuliqing", 28); } }; } }

客戶端調(diào)用服務(wù)端接口代碼以下:

public class MainActivity extends AppCompatActivity { private IMyAidlInterface iMyAidlInterface = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override protected void onStart() { super.onStart(); Intent intent = new Intent(this, RemoteService.class); bindService(intent, serviceConnection, BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); unbindService(serviceConnection); } private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { iMyAidlInterface = null; } }; public void onClickToSayHello(View view) { if (iMyAidlInterface != null) { try { HelloMsg helloMsg = iMyAidlInterface.sayHello(); Toast.makeText(this, helloMsg.toString(), Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show(); } } } }

onServiceConnected()回調(diào)中,我們使用IMyAidlInterface.Stub.asInterface(service)方法返回我們的接口的援用。接著客戶端就能夠通過它來對(duì)服務(wù)端發(fā)送要求了。

在這里我為RemoteService設(shè)置了process屬性,讓它運(yùn)行在與默許進(jìn)程不同的進(jìn)程中。

<service android:name="RemoteService" android:process=":remote" />

從上圖可看出客戶端和服務(wù)運(yùn)行在兩個(gè)進(jìn)程當(dāng)中。

然后點(diǎn)擊按鈕,成功返回結(jié)果。

最后給出1張流程圖,加深印象:


關(guān)于AIDL和binder機(jī)制可參考下面文章:

Android中AIDL的基本用法

Binder機(jī)制和遠(yuǎn)程服務(wù)調(diào)用機(jī)制分析

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 黄色网页入口 | 国产美女视频一区 | 日本精品中文字幕 | 99久久er热在这里只有精品15 | 亚洲免费视频一区二区 | 老司机av福利| 久久久久无码国产精品一区 | 日韩午夜视频在线观看 | 中文字幕在线观看第一页 | 99热这里只有精品2 国产福利在线导航 | 国产区一区 | 国产99视频精品免视看9 | 色婷婷亚洲综合 | 中文字幕一二三 | 精品视频一二三区 | 中国成人在线视频 | 国产精品麻豆欧美日韩ww | 国产一二三在线观看 | 国产精品国产馆在线真实露脸 | av中文在线 | 黄色免费视频在线观看 | 久久国产精品一区二区 | 黄网入口 | 精品专区 | 亚洲视频免费在线观看 | 亚洲国产综合在线 | 中文字幕成人av | 黄色网址在线播放 | 日韩精品在线一区 | 久久精品成人欧美大片 | 国产在线高清 | 日韩在线视频在线 | 黄色电影在线免费看 | 麻豆国产在线 | 日韩免费在线视频 | 一区在线不卡 | 日韩欧美一区二区三区在线视频 | 国产视频一区二区 | 爱久久久 | 久久久久久久网 | 老牛影视av一区二区在线观看 |