Android Studio中AIDL使用方法
一、簡介:
AIDL:Android Interface Define Language(Android介面定義語言),主要用於服務端與客戶端程序間通訊(服務端與多客戶端)
二、配置
Android Studio中使用(最好採用project模式)
1、第一類:
簡單資料傳遞(基本資料型別,String ,List,Map)
<1>服務端配置(不需要介面)
①.建立aidl自定義介面檔案 —IMyAidlInterface.aidl
步驟:File –> New –> AIDL –> AIDL File
然後可以看到在src/main目錄下生成了一個目錄aidl,點開aidl,可以看到剛才建立的IMyAidlInterface.aidl檔案
IMyAidlInterface.aidl程式碼如下:
package com.example.lambert.aidltest;
interface IMyAidlInterface {
String getValue();
}
②編譯(因為Android Studio不能像Eclipse那樣自動編譯aidl檔案,所以需要手動編譯)
點選Build –> Make Module’server’
然後可以看到在build/generated/source/debug/com.example.lambert.aidlproject/目錄下生成了一個檔案IMyAidlInterface,表示編譯成功;
③編寫Service
package com.example.lambert.aidltest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
//記得要return一個IMyService,否則客戶端呼叫的時候會報空指標
return new IMyService();
}
public class IMyService extends IMyAidlInterface.Stub {
@Override
public String getValue() throws RemoteException {
return "This is Lambert Server";
}
}
}
④在AndroidMenifest.xml中對Service進行配置:
<!-- MyService -->
<service
android:name=".MyService"
android:process=":remote">
<intent-filter>
<action android:name="com.example.lambert.aidlproject.MyService" />
</intent-filter>
</service>
到此為止,服務端配置完畢。
<2>客戶端配置
①需要將服務端配置的整個aidl目錄一併拷貝到客戶端所在工程src/main目錄下(包名與檔名必須與服務端一模一樣)
②編譯(同服務端)
③繫結服務
MainActivity.java
package com.example.lambert.client;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.example.lambert.aidlproject.IMyAidlInterface;
import com.example.lambert.aidlproject.Person;
public class MainActivity extends Activity implements View.OnClickListener {
private IMyAidlInterface mService;
private Button btn_bind, btn_get;
private TextView tv;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
btn_bind = (Button) findViewById(R.id.btn_bind);
btn_get = (Button) findViewById(R.id.btn_get);
tv = (TextView) findViewById(R.id.tv);
btn_bind.setOnClickListener(this);
btn_get.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_bind:
Intent intent = new Intent();
intent.setAction("com.example.lambert.aidlproject.MyService");
//從 Android 5.0開始 隱式Intent繫結服務的方式已不能使用,所以這裡需要設定Service所在服務端的包名
intent.setPackage("com.example.lambert.aidlproject");
bindService(intent, connection, Context.BIND_AUTO_CREATE);
break;
case R.id.btn_get:
try {
String str = mService.getValue();
tv.setText(str);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (serviceConnection != null) {
unbindService(connection);
}
}
}
通過 mService = IMyAidlInterface.Stub.asInterface(service); 可以獲取到服務端的代理物件,從而可以通過回撥方法從服務端獲取到我們所需的資料。
2.第二類:自定義複雜資料型別(Parcelable)
<1>服務端配置(不需要介面)
①.在上述aidl目錄下建立複雜資料物件aidl檔案(這裡以Person.aidl為例)對複雜物件進行宣告:
Person.aidl
// Person.aidl
package com.example.lambert.aidlproject;
parcelable Person;
②在src/main/java目錄下建立Person.java檔案
Person.java
package com.example.lambert.aidlproject;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable {
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
private String name;
public Person(String name) {
this.name = name;
}
protected Person(Parcel in) {
name = in.readString();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
}
}
③修改IMyAidlInterface.aidl如下:
package com.example.lambert.aidlproject;
//PS:這裡需要注意import匯入Person,第一類不需要匯入
import com.example.lambert.aidlproject.Person;
interface IMyAidlInterface {
Person getValue();
}
④Service類也做出相應修改
public class IMyService extends IMyAidlInterface.Stub {
@Override
public Person getValue() throws RemoteException {
return new Person("Rose");
}
}
}
⑤編譯(同上)
到此為止,服務端配置完畢。
<2>客戶端配置
①拷貝Person.aidl和Person.java檔案到客戶端工程下:
Person.aidl可以拷貝到aidl目錄下:
Person.java檔案需要拷貝到src/main/java目錄下,並且所在包名必須與服務端保持一致,但是客戶端工程包名與服務端包名未必一致,所以在這裡我們需要重新建立一個包com.example.lambert.aidlproject(服務端工程包名),並將Person.java檔案拷貝至此;
另:IMyAidlInterface.aidl做同上修改,當然也可以直接拷貝過來
②編譯(同上)
③MainActivity程式碼也做相應修改
try {
Person person = mService.getValue();
tv.setText(person.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
客戶端配置完畢。
關於AIDL在Android Studio中的使用暫且簡單介紹到這裡。