android aidl工具,【Android】AIDL介绍和实例讲解
前言
為使應用程序之間能夠彼此通信,Android提供了IPC (Inter Process Communication,進程間通信)的一種獨特實現: AIDL (Android Interface Definition Language, Android接口定義語言)。
網上看了幾篇關于AIDL的文章,寫得都很不錯,不過例子構造大多略微復雜: 建立兩個Android項目,一個是client,一個是server(提供service)。
這篇文章將通過一個項目來介紹AIDL用法,包含了service和client。可能簡單了些,不過輕省許多。
這篇博文包含以下三個部分:
1、AIDL介紹
2、定義
3、用例: HelloSumAIDL
3.1、創建工程
3.2、定義AIDL文件
3.3、實現遠程服務(Service)
3.4、“暴露”服務
3.5、相關代碼
一、 AIDL介紹
在Android中,每個應用(Application)執行在它自己的進程中,無法直接調用到其他應用的資源,這也符合“沙箱”的理念。所謂沙箱原理,一般來說用在移動電話業務中,簡單地說旨在部分地或全部地隔離應用程序。關于沙箱技術我們這里就不多做介紹了,可以參看51CTO的這篇文章。
因此,在Android中,當一個應用被執行時,一些操作是被限制的,比如訪問內存,訪問傳感器,等等。這樣做可以最大化地保護系統,免得應用程序“為所欲為”。
那我們有時需要在應用間交互,怎么辦呢?于是,Android需要實現IPC協議。然而,這個協議還是有點復雜,主要因為需要實現數據管理系統(在進程或線程間傳遞數據)。為了暫時減緩這個“會呼吸的痛”,Android為我們實現了自己的IPC,也就是梁靜茹,oh,sorry,是AIDL :]
二、 定義
AIDL是IPC的一個輕量級實現,用了對于Java開發者來說很熟悉的語法。Android也提供了一個工具,可以自動創建Stub(類構架,類骨架)。當我們需要在應用間通信時,我們需要按以下幾步走:
1. 定義一個AIDL接口
2. 為遠程服務(Service)實現對應Stub
3. 將服務“暴露”給客戶程序使用
三、 用例: HelloSumAIDL
AIDL的語法很類似Java的接口(Interface),只需要定義方法的簽名。
AIDL支持的數據類型與Java接口支持的數據類型有些不同
1. 所有基礎類型(int, char, 等)
2. String,List,Map,CharSequence等類
3. 其他AIDL接口類型
4. 所有Parcelable的類
為了更好地展示AIDL的用法,我們來看一個很簡單的例子: 兩數相加。
3.1創建工程
事不宜遲,我們就創建一個Android項目。以下是項目的基本信息(不一定要一樣):
- 項目名稱: HelloSumAIDL
- 目標平臺: 4.3
- 包名: com.android.hellosumaidl
- Activity名稱: HelloSumAidlActivity
3.2創建工程
在com.android.hellosumaidl這個包中,新建一個普通文件(New->File),取名為 IAdditionService.aidl。在這個文件中輸入以下代碼:
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工具會在gen/com/android/hellosumaidl這個文件夾里自動生成對應的IAdditionService.java這個文件。因為是自動生成的,所以無需改動。這個文件里就包含了Stub,我們接下來要為我們的遠程服務實現這個Stub。
3.3實現遠程服務
首先我們在com.android.hellosumaidl這個包中新建一個類,取名叫AdditionService.java。為了實現我們的服務,我們需要讓這個類中的onBind方法返回一個IBinder類的對象。這個IBinder類的對象就代表了遠程服務的實現。為了實現這個服務,我們要用到自動生成的子類IAdditionService.Stub。在其中,我們也必須實現我們之前在AIDL文件中定義的add()函數。下面是我們遠程服務的代碼:
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“暴露”服務
一旦實現了服務中的onBind方法,我們就可以把客戶程序(在這里是HelloSumAidlActivity.java)與服務連接起來了。為了建立這樣的一個鏈接,我們需要實現ServiceConnection類。我們在HelloSumAidlActivity.java創建一個內部類AdditionServiceConnection,這個類繼承ServiceConnection類,并且重寫了它的兩個方法:onServiceConnected和onServiceDisconnected。下面給出內部類的代碼:
/*
*?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();
}
}
這個方法接收一個遠程服務的實現作為參數。這個實現隨后被轉換(cast)為我們自己的AIDL的實現。我們使用 IAdditionService.Stub.asInterface((IBinder)boundService)。
3.5相關代碼
為了完成我們的測試項目,我們需要首先改寫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;
}
}
將此項目運行起來,得到的兩個截圖如下:
Fig 1 : 填寫數字前
Fig 2 : 按下計算按鈕后
后記
總結
以上是生活随笔為你收集整理的android aidl工具,【Android】AIDL介绍和实例讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: echart 三维可视化地图_揭秘720
- 下一篇: android系统签名app自动更新,【