android aidl工具,【Android】AIDL介绍和实例讲解
前言
為使應(yīng)用程序之間能夠彼此通信,Android提供了IPC (Inter Process Communication,進(jìn)程間通信)的一種獨(dú)特實(shí)現(xiàn): AIDL (Android Interface Definition Language, Android接口定義語(yǔ)言)。
網(wǎng)上看了幾篇關(guān)于AIDL的文章,寫得都很不錯(cuò),不過(guò)例子構(gòu)造大多略微復(fù)雜: 建立兩個(gè)Android項(xiàng)目,一個(gè)是client,一個(gè)是server(提供service)。
這篇文章將通過(guò)一個(gè)項(xiàng)目來(lái)介紹AIDL用法,包含了service和client。可能簡(jiǎn)單了些,不過(guò)輕省許多。
這篇博文包含以下三個(gè)部分:
1、AIDL介紹
2、定義
3、用例: HelloSumAIDL
3.1、創(chuàng)建工程
3.2、定義AIDL文件
3.3、實(shí)現(xiàn)遠(yuǎn)程服務(wù)(Service)
3.4、“暴露”服務(wù)
3.5、相關(guān)代碼
一、 AIDL介紹
在Android中,每個(gè)應(yīng)用(Application)執(zhí)行在它自己的進(jìn)程中,無(wú)法直接調(diào)用到其他應(yīng)用的資源,這也符合“沙箱”的理念。所謂沙箱原理,一般來(lái)說(shuō)用在移動(dòng)電話業(yè)務(wù)中,簡(jiǎn)單地說(shuō)旨在部分地或全部地隔離應(yīng)用程序。關(guān)于沙箱技術(shù)我們這里就不多做介紹了,可以參看51CTO的這篇文章。
因此,在Android中,當(dāng)一個(gè)應(yīng)用被執(zhí)行時(shí),一些操作是被限制的,比如訪問(wèn)內(nèi)存,訪問(wèn)傳感器,等等。這樣做可以最大化地保護(hù)系統(tǒng),免得應(yīng)用程序“為所欲為”。
那我們有時(shí)需要在應(yīng)用間交互,怎么辦呢?于是,Android需要實(shí)現(xiàn)IPC協(xié)議。然而,這個(gè)協(xié)議還是有點(diǎn)復(fù)雜,主要因?yàn)樾枰獙?shí)現(xiàn)數(shù)據(jù)管理系統(tǒng)(在進(jìn)程或線程間傳遞數(shù)據(jù))。為了暫時(shí)減緩這個(gè)“會(huì)呼吸的痛”,Android為我們實(shí)現(xiàn)了自己的IPC,也就是梁靜茹,oh,sorry,是AIDL :]
二、 定義
AIDL是IPC的一個(gè)輕量級(jí)實(shí)現(xiàn),用了對(duì)于Java開發(fā)者來(lái)說(shuō)很熟悉的語(yǔ)法。Android也提供了一個(gè)工具,可以自動(dòng)創(chuàng)建Stub(類構(gòu)架,類骨架)。當(dāng)我們需要在應(yīng)用間通信時(shí),我們需要按以下幾步走:
1. 定義一個(gè)AIDL接口
2. 為遠(yuǎn)程服務(wù)(Service)實(shí)現(xiàn)對(duì)應(yīng)Stub
3. 將服務(wù)“暴露”給客戶程序使用
三、 用例: HelloSumAIDL
AIDL的語(yǔ)法很類似Java的接口(Interface),只需要定義方法的簽名。
AIDL支持的數(shù)據(jù)類型與Java接口支持的數(shù)據(jù)類型有些不同
1. 所有基礎(chǔ)類型(int, char, 等)
2. String,List,Map,CharSequence等類
3. 其他AIDL接口類型
4. 所有Parcelable的類
為了更好地展示AIDL的用法,我們來(lái)看一個(gè)很簡(jiǎn)單的例子: 兩數(shù)相加。
3.1創(chuàng)建工程
事不宜遲,我們就創(chuàng)建一個(gè)Android項(xiàng)目。以下是項(xiàng)目的基本信息(不一定要一樣):
- 項(xiàng)目名稱: HelloSumAIDL
- 目標(biāo)平臺(tái): 4.3
- 包名: com.android.hellosumaidl
- Activity名稱: HelloSumAidlActivity
3.2創(chuàng)建工程
在com.android.hellosumaidl這個(gè)包中,新建一個(gè)普通文件(New->File),取名為 IAdditionService.aidl。在這個(gè)文件中輸入以下代碼:
package?com.android.hellosumaidl;
//?Interface?declaration
interface?IAdditionService?{
//?You?can?pass?the?value?of?in,?out?or?inout
//?The?primitive?types?(int,?boolean,?etc)?are?only?passed?by?in
int?add(in?int?value1,?in?int?value2);
}
一旦文件被保存,Android的AIDL工具會(huì)在gen/com/android/hellosumaidl這個(gè)文件夾里自動(dòng)生成對(duì)應(yīng)的IAdditionService.java這個(gè)文件。因?yàn)槭亲詣?dòng)生成的,所以無(wú)需改動(dòng)。這個(gè)文件里就包含了Stub,我們接下來(lái)要為我們的遠(yuǎn)程服務(wù)實(shí)現(xiàn)這個(gè)Stub。
3.3實(shí)現(xiàn)遠(yuǎn)程服務(wù)
首先我們?cè)赾om.android.hellosumaidl這個(gè)包中新建一個(gè)類,取名叫AdditionService.java。為了實(shí)現(xiàn)我們的服務(wù),我們需要讓這個(gè)類中的onBind方法返回一個(gè)IBinder類的對(duì)象。這個(gè)IBinder類的對(duì)象就代表了遠(yuǎn)程服務(wù)的實(shí)現(xiàn)。為了實(shí)現(xiàn)這個(gè)服務(wù),我們要用到自動(dòng)生成的子類IAdditionService.Stub。在其中,我們也必須實(shí)現(xiàn)我們之前在AIDL文件中定義的add()函數(shù)。下面是我們遠(yuǎn)程服務(wù)的代碼:
package?com.android.hellosumaidl;
import?android.app.Service;
import?android.content.Intent;
import?android.os.IBinder;
import?android.os.RemoteException;
/*
*?This?class?exposes?the?service?to?client
*/
public?class?AdditionService?extends?Service?{
@Override
public?void?onCreate()?{
super.onCreate();
}
@Override
public?IBinder?onBind(Intent?intent)?{
return?new?IAdditionService.Stub()?{
/*
*?Implement?com.android.hellosumaidl.IAdditionService.add(int,?int)
*/
@Override
public?int?add(int?value1,?int?value2)?throws?RemoteException?????????????{
return?value1?+?value2;
}
};
}
@Override
public?void?onDestroy()?{
super.onDestroy();
}
}
3.4“暴露”服務(wù)
一旦實(shí)現(xiàn)了服務(wù)中的onBind方法,我們就可以把客戶程序(在這里是HelloSumAidlActivity.java)與服務(wù)連接起來(lái)了。為了建立這樣的一個(gè)鏈接,我們需要實(shí)現(xiàn)ServiceConnection類。我們?cè)贖elloSumAidlActivity.java創(chuàng)建一個(gè)內(nèi)部類AdditionServiceConnection,這個(gè)類繼承ServiceConnection類,并且重寫了它的兩個(gè)方法:onServiceConnected和onServiceDisconnected。下面給出內(nèi)部類的代碼:
/*
*?This?inner?class?is?used?to?connect?to?the?service
*/
class?AdditionServiceConnection?implements?ServiceConnection?{
public?void?onServiceConnected(ComponentName?name,?IBinder?boundService)?{
service?=?IAdditionService.Stub.asInterface((IBinder)boundService);
Toast.makeText(HelloSumAidlActivity.this,?"Service?connected",?Toast.LENGTH_LONG).show();
}
public?void?onServiceDisconnected(ComponentName?name)?{
service?=?null;
Toast.makeText(HelloSumAidlActivity.this,?"Service?disconnected",?Toast.LENGTH_LONG).show();
}
}
這個(gè)方法接收一個(gè)遠(yuǎn)程服務(wù)的實(shí)現(xiàn)作為參數(shù)。這個(gè)實(shí)現(xiàn)隨后被轉(zhuǎn)換(cast)為我們自己的AIDL的實(shí)現(xiàn)。我們使用 IAdditionService.Stub.asInterface((IBinder)boundService)。
3.5相關(guān)代碼
為了完成我們的測(cè)試項(xiàng)目,我們需要首先改寫main.xml(主界面的格局文件)和string.xml(字符串定義文件):
main.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"?>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:textSize="22sp"?/>
android:id="@+id/value1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/hint1"?>
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/plus"
android:textSize="36sp"?/>
android:id="@+id/value2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/hint2"?>
android:id="@+id/buttonCalc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/equal"?>
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/result"
android:textSize="36sp"?/>
string.xml
HelloSumAIDL
Hello?Sum?AIDL
Result
+
=
Value?1
Value?2
最后,我們的HelloSumAidlActivity.java如下:
package?com.android.hellosumaidl;
import?android.os.Bundle;
import?android.os.IBinder;
import?android.os.RemoteException;
import?android.view.View;
import?android.view.View.OnClickListener;
import?android.widget.Button;
import?android.widget.EditText;
import?android.widget.TextView;
import?android.widget.Toast;
import?android.app.Activity;
import?android.content.ComponentName;
import?android.content.Context;
import?android.content.Intent;
import?android.content.ServiceConnection;
public?class?HelloSumAidlActivity?extends?Activity?{
IAdditionService?service;
AdditionServiceConnection?connection;
@Override
public?void?onCreate(Bundle?savedInstanceState)?{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initService();
Button?buttonCalc?=?(Button)findViewById(R.id.buttonCalc);
buttonCalc.setOnClickListener(new?OnClickListener()?{
TextView?result?=?(TextView)findViewById(R.id.result);
EditText?value1?=?(EditText)findViewById(R.id.value1);
EditText?value2?=?(EditText)findViewById(R.id.value2);
@Override
public?void?onClick(View?v)?{
int?v1,?v2,?res?=?-1;
v1?=?Integer.parseInt(value1.getText().toString());
v2?=?Integer.parseInt(value2.getText().toString());
try?{
res?=?service.add(v1,?v2);
}?catch?(RemoteException?e)?{
e.printStackTrace();
}
result.setText(Integer.valueOf(res).toString());
}
});
}
@Override
protected?void?onDestroy()?{
super.onDestroy();
releaseService();
}
/*
*?This?inner?class?is?used?to?connect?to?the?service
*/
class?AdditionServiceConnection?implements?ServiceConnection?{
public?void?onServiceConnected(ComponentName?name,?IBinder?boundService)?{
service?=?IAdditionService.Stub.asInterface((IBinder)boundService);
Toast.makeText(HelloSumAidlActivity.this,?"Service?connected",?Toast.LENGTH_LONG).show();
}
public?void?onServiceDisconnected(ComponentName?name)?{
service?=?null;
Toast.makeText(HelloSumAidlActivity.this,?"Service?disconnected",?Toast.LENGTH_LONG).show();
}
}
/*
*?This?function?connects?the?Activity?to?the?service
*/
private?void?initService()?{
connection?=?new?AdditionServiceConnection();
Intent?i?=?new?Intent();
i.setClassName("com.android.hellosumaidl",?com.android.hellosumaidl.AdditionService.class.getName());
boolean?ret?=?bindService(i,?connection,?Context.BIND_AUTO_CREATE);
}
/*
*?This?function?disconnects?the?Activity?from?the?service
*/
private?void?releaseService()?{
unbindService(connection);
connection?=?null;
}
}
將此項(xiàng)目運(yùn)行起來(lái),得到的兩個(gè)截圖如下:
Fig 1 : 填寫數(shù)字前
Fig 2 : 按下計(jì)算按鈕后
后記
總結(jié)
以上是生活随笔為你收集整理的android aidl工具,【Android】AIDL介绍和实例讲解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: echart 三维可视化地图_揭秘720
- 下一篇: java classpath设置_Jav