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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

AIDL

發布時間:2023/12/4 综合教程 45 生活家
生活随笔 收集整理的這篇文章主要介紹了 AIDL 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Android中,如果我們需要在不同進程間實現通信,就需要用到AIDL技術去完成。

AIDL(Android Interface Definition Language)是一種接口定義語言,編譯器通過*.aidl文件的描述信息生成符合通信協議的Java代碼,我們無需自己去寫這段繁雜的代碼,只需要在需要的時候調用即可,通過這種方式我們就可以完成進程間的通信工作。關于AIDL的編寫規則我在這里就不多介紹了,讀者可以到網上查找一下相關資料。

接下來,我就演示一個操作AIDL的最基本的流程。

首先,我們需要建立一個服務端的工程,如圖所以:

在IPerson.aidl中我們定義了一個“問候”的方法,代碼如下:

[java]view plaincopy

packagecom.scott.aidl;
interfaceIPerson{
Stringgreet(Stringsomeone);
}

在Eclipse插件的幫助下,編譯器會自動在gen目錄中生成對應的IPerson.java文件,格式化后的代碼如下:

[java]view plaincopy

packagecom.scott.aidl;

publicinterfaceIPersonextendsandroid.os.IInterface{
/**Local-sideIPCimplementationstubclass.*/
publicstaticabstractclassStubextendsandroid.os.Binderimplementscom.scott.aidl.IPerson{

privatestaticfinaljava.lang.StringDESCRIPTOR="com.scott.aidl.IPerson";

/**Constructthestubatattachittotheinterface.*/
publicStub(){
this.attachInterface(this,DESCRIPTOR);
}

/**
*CastanIBinderobjectintoancom.scott.aidl.IPersoninterface,
*generatingaproxyifneeded.
*/
publicstaticcom.scott.aidl.IPersonasInterface(android.os.IBinderobj){
if((obj==null)){
returnnull;
}
android.os.IInterfaceiin=(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if(((iin!=null)&&(iininstanceofcom.scott.aidl.IPerson))){
return((com.scott.aidl.IPerson)iin);
}
returnnewcom.scott.aidl.IPerson.Stub.Proxy(obj);
}

publicandroid.os.IBinderasBinder(){
returnthis;
}

@Override
publicbooleanonTransact(intcode,android.os.Parceldata,android.os.Parcelreply,intflags)
throwsandroid.os.RemoteException{
switch(code){
caseINTERFACE_TRANSACTION:{
reply.writeString(DESCRIPTOR);
returntrue;
}
caseTRANSACTION_greet:{
data.enforceInterface(DESCRIPTOR);
java.lang.String_arg0;
_arg0=data.readString();
java.lang.String_result=this.greet(_arg0);
reply.writeNoException();
reply.writeString(_result);
returntrue;
}
}
returnsuper.onTransact(code,data,reply,flags);
}

privatestaticclassProxyimplementscom.scott.aidl.IPerson{
privateandroid.os.IBindermRemote;

Proxy(android.os.IBinderremote){
mRemote=remote;
}

publicandroid.os.IBinderasBinder(){
returnmRemote;
}

publicjava.lang.StringgetInterfaceDescriptor(){
returnDESCRIPTOR;
}

publicjava.lang.Stringgreet(java.lang.Stringsomeone)throwsandroid.os.RemoteException{
android.os.Parcel_data=android.os.Parcel.obtain();
android.os.Parcel_reply=android.os.Parcel.obtain();
java.lang.String_result;
try{
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(someone);
mRemote.transact(Stub.TRANSACTION_greet,_data,_reply,0);
_reply.readException();
_result=_reply.readString();
}finally{
_reply.recycle();
_data.recycle();
}
return_result;
}
}

staticfinalintTRANSACTION_greet=(android.os.IBinder.FIRST_CALL_TRANSACTION+0);
}

publicjava.lang.Stringgreet(java.lang.Stringsomeone)throwsandroid.os.RemoteException;
}

該文件的大綱視圖如下:

IPerson接口中的抽象內部類Stub繼承android.os.Binder類并實現IPerson接口,比較重要的方法是asInterface(IBinder)方法,該方法會將IBinder類型的對象轉換成IPerson類型,必要的時候生成一個代理對象返回結果。

接下來就是我們的Service了:

[java]view plaincopy

packagecom.scott.server;

importandroid.app.Service;
importandroid.content.Intent;
importandroid.os.IBinder;
importandroid.os.RemoteException;
importandroid.util.Log;

importcom.scott.aidl.IPerson;

publicclassAIDLServiceextendsService{

privatestaticfinalStringTAG="AIDLService";

IPerson.Stubstub=newIPerson.Stub(){
@Override
publicStringgreet(Stringsomeone)throwsRemoteException{
Log.i(TAG,"greet()called");
return"hello,"+someone;
}
};

@Override
publicIBinderonBind(Intentintent){
Log.i(TAG,"onBind()called");
returnstub;
}

@Override
publicbooleanonUnbind(Intentintent){
Log.i(TAG,"onUnbind()called");
returntrue;
}

@Override
publicvoidonDestroy(){
super.onDestroy();
Log.i(TAG,"onDestroy()called");
}
}

我們實現了IPerson.Stub這個抽象類的greet方法,然后再onBind(Intent)方法中返回我們的stub實例,這樣一來調用方獲取的IPerson.Stub就是我們的這個實例,greet方法也會按照我們的期望那樣執行。

當然,要想讓Service生效,我們還需要在AndroidManifest.xml中做一些配置工作:

[java]view plaincopy

<serviceandroid:name=".AIDLService">
<intent-filter>
<actionandroid:name="android.intent.action.AIDLService"/>
<categoryandroid:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>

服務端已經完成了,接下來我們就該完成客戶端的工作了。我已經建好了一個客戶端工程,如圖:

我們只需要把IPerson.aidl文件拷到相應的目錄中即可,編譯器同樣會生成相對應的IPerson.java文件,這一部分和服務端沒什么區別。這樣一來,服務端和客戶端就在通信協議上達到了統一。我們主要工作在MainActivity中完成。

MainActivity代碼如下:

[java]view plaincopy

packagecom.scott.client;

importandroid.app.Activity;
importandroid.content.ComponentName;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.content.ServiceConnection;
importandroid.os.Bundle;
importandroid.os.IBinder;
importandroid.os.RemoteException;
importandroid.util.Log;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.Toast;

importcom.scott.aidl.IPerson;

publicclassMainActivityextendsActivity{

privateButtonbindBtn;
privateButtongreetBtn;
privateButtonunbindBtn;

privateIPersonperson;
privateServiceConnectionconn=newServiceConnection(){

@Override
publicvoidonServiceConnected(ComponentNamename,IBinderservice){
Log.i("ServiceConnection","onServiceConnected()called");
person=IPerson.Stub.asInterface(service);
}

@Override
publicvoidonServiceDisconnected(ComponentNamename){
//Thisiscalledwhentheconnectionwiththeservicehasbeenunexpectedlydisconnected,
//thatis,itsprocesscrashed.Becauseitisrunninginoursameprocess,weshouldneverseethishappen.
Log.i("ServiceConnection","onServiceDisconnected()called");
}
};

@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

bindBtn=(Button)findViewById(R.id.bindBtn);
bindBtn.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
Intentintent=newIntent("android.intent.action.AIDLService");
bindService(intent,conn,Context.BIND_AUTO_CREATE);

bindBtn.setEnabled(false);
greetBtn.setEnabled(true);
unbindBtn.setEnabled(true);
}
});

greetBtn=(Button)findViewById(R.id.greetBtn);
greetBtn.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
try{
StringretVal=person.greet("scott");
Toast.makeText(MainActivity.this,retVal,Toast.LENGTH_SHORT).show();
}catch(RemoteExceptione){
Toast.makeText(MainActivity.this,"error",Toast.LENGTH_SHORT).show();
}
}
});

unbindBtn=(Button)findViewById(R.id.unbindBtn);
unbindBtn.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
unbindService(conn);

bindBtn.setEnabled(true);
greetBtn.setEnabled(false);
unbindBtn.setEnabled(false);
}
});
}
}

從代碼中可以看到,我們要重寫ServiceConnection中的onServiceConnected方法將IBinder類型的對像轉換成我們的IPerson類型。到現在我們就剩下最后一個步驟了,這個環節也是最為關鍵的,就是綁定我們需要的服務。我們通過服務端Service定義的“android.intent.action.AIDLService”這個標識符來綁定其服務,這樣客戶端和服務端就實現了通信的連接,我們就可以調用IPerson中的“問候”方法了。

最后,貼幾張客戶端演示過程圖。

按照順序分別是:初始界面;點擊bindService后界面;點擊greet后界面;點擊unbindService后界面。

操作過程中的日志如下:


總結

以上是生活随笔為你收集整理的AIDL的全部內容,希望文章能夠幫你解決所遇到的問題。

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