接着剛剛的一篇講下使用AIDL傳遞對象的過程,AIDL在不導入其他包的情況下支持如下幾種數據類型:
1. 基本數據類型(boolean、char、byte、int、long、float、double),注意:不支持short
2. String和CharSequence
3. List和Map
4. Parcelable:
傳遞對象必須要實現序列化,ADIL中序列化對象的流程如下:
1)序列化對象
2)建立對象的.aidl文件,名稱要一樣
3)建立.aidl文件,手動導入對象,聲明對象是in還是out
接上一篇,看下工程結構,IDemoAidlInterface大家不用管,是上一篇的內容:
先看下怎麼序列化對象,首先創建Person類,實現Parcelable接口,具體方法怎麼使用看註釋
/**
* 序列化
*
* @author yuzhentao
*/
public class Person implements Parcelable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
/**
* 內容接口描述,默認返回0就可以
*
* @return int
*/
@Override
public int describeContents() {
return 0;
}
/**
* 將對象序列化爲一個Parcel對象
* 將類的數據寫入外部提供的Parcel中,打包需要傳遞的數據到Parcel容器保存,以便從Parcel容器獲取數據
*
* @param dest:Parcel
* @param flags:int
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
protected Person(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
}
/**
* 實例化靜態內部對象CREATOR實現接口Parcelable.Creator
*/
public static final Creator<Person> CREATOR = new Creator<Person>() {
/**
* 從Parcel容器中讀取傳遞數據值,封裝成Parcelable對象返回邏輯層
* @param in:Parcel
* @return Person
*/
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
/**
*創建一個類型爲<T>,長度爲size的數組,供外部類反序列化本類數組使用
* @param size:int
* @return Person[]
*/
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
然後建立對象的.aidl文件,名稱要一樣,寫法是
package yuzhentao.aidldemo;
//必須這樣寫
parcelable Person;
然後建立.aidl文件,手動導入對象,聲明對象是in還是out,這裏切記一定要手動導入一下
package yuzhentao.aidldemo;
//手動導入
import yuzhentao.aidldemo.Person;
interface IParcelableAidlInterface {
//一定要帶上in或者out,告訴這個Person是輸入還是輸出的
List<Person> add(in Person person);
}
接着就是修改Service的內容了,將接口更改一下即可,然後返回ArrayList<Person>
/**
* Aidl服務
*
* @author yuzhentao
*/
public class IDemoAidlService extends Service {
private ArrayList<Person> personList;
/**
* 當客服端綁定到服務端時會執行
*
* @param intent:Intent
* @return IBinder
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
// return iBinder;
personList = new ArrayList<>();
return iBinderPerson;
}
// private IBinder iBinder = new IDemoAidlInterface.Stub() {
// @Override
// public int add(int num1, int num2) throws RemoteException {
// Log.e("yzt", "收到遠程請求,輸入的參數是:" + num1 + "和" + num2);
// return num1 + num2;
// }
// };
private IBinder iBinderPerson = new IParcelableAidlInterface.Stub() {
@Override
public List<Person> add(Person person) throws RemoteException {
personList.add(person);
return personList;
}
};
}
服務端準備完畢,接着將這些文件包括複製到客戶端,包名一定要一樣,看下客戶端的結構,同樣請無視IDemoAidlInterface
客戶端同樣將接口修改一下,點擊時實例化一個ArrayList<Person>,通過接口的方法傳遞到服務端,打印Log看下結果
/**
* 客戶端
* 獲取服務端
* .aidl必須和服務端的一樣,包括包名,負責編譯不通過
* 如果有序列化對象,連同包名也必須一樣
*
* @author yuzhentao
*/
public class MainActivity extends Activity {
// private IDemoAidlInterface iDemoAidlInterface;
private IParcelableAidlInterface iParcelableAidlInterface;
/**
* 服務連接接口
*/
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {//連接服務時執行,ComponentName是bindService()指定的,IBinder是服務端的onBind()返回的
// iDemoAidlInterface = IDemoAidlInterface.Stub.asInterface(service);//返回IDemoAidlInterface,拿到了遠程的服務的代理
iParcelableAidlInterface = IParcelableAidlInterface.Stub.asInterface(service);//返回IDemoAidlInterface,拿到了遠程的服務的代理
}
@Override
public void onServiceDisconnected(ComponentName name) {//斷開服務時執行
// iDemoAidlInterface = null;
iParcelableAidlInterface = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
bindService();//綁定服務
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);//解綁服務
}
private void initView() {
// final EditText etNum1 = (EditText) findViewById(R.id.edittext_num1_activity_main);
// final EditText etNum2 = (EditText) findViewById(R.id.edittext_num2_activity_main);
// final EditText etResult = (EditText) findViewById(R.id.edittext_result_activity_main);
findViewById(R.id.button_activity_main).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// int num1 = Integer.parseInt(etNum1.getText().toString());
// int num2 = Integer.parseInt(etNum2.getText().toString());
// String result;
// try {
// result = iDemoAidlInterface.add(num1, num2) + "";//調用遠程的服務
// etResult.setText(result);
// } catch (RemoteException e) {
// e.printStackTrace();
// etResult.setText("發生錯誤");
// }
try {
ArrayList<Person> personList = (ArrayList<Person>) iParcelableAidlInterface.add(new Person("yuzhentao", 25));
Log.e("yzt", personList.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
/**
* 綁定服務
* alt+command+m:提取方法
*/
private void bindService() {
Intent intent = new Intent();
intent.setComponent(new ComponentName("yuzhentao.aidldemo", "yuzhentao.aidldemo.IDemoAidlService"));//顯式Intent
bindService(intent, conn, Context.BIND_AUTO_CREATE);//綁定服務
}
}
03-14 14:38:49.319 31540-31540/yuzhentao.aidldemoclient E/yzt: [Person{name='yuzhentao', age=25}]
這裏沒有效果圖,在此感謝下慕課網