AIDL进程间传递复杂数据类型系列:
AIDL进程间传递复杂数据类型—AIDL传递其他AIDL接口
AIDL进程间传递复杂数据类型—AIDL传递android.os.Parcelable接口
=========================================
前面我们讲到了AIDL进程间传递复杂数据类型—AIDL传递其他AIDL接口,现在我们接着来说第二种了。就是AIDL传递android.os.Parcelable接口类型的数据。
我们继续在前面的代码基础上进行丰富,由于这里的代码是接着AIDL进程间传递复杂数据类型—AIDL传递其他AIDL接口来写的,它包含有前面写的代码,所以建议把前面这篇文章看看。
Person.aidl文件
package com.xxx.cn.client;
parcelable Person;
Person.java文件
//Person.java
package com.xxx.cn.client;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable {
private String mName;
private int mSex;
//必须提供一个名为CREATOR的static final属性 该属性需要实现android.os.Parcelable.Creator<T>接口
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
return new Person(source.readString(), source.readInt());
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
public Person() {}
private Person(String name, int sex) {
mName = name;
mSex = sex;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mName);
dest.writeInt(mSex);
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public int getSex() {
return mSex;
}
public void setSex(int sex) {
mSex = sex;
}
}
客户端和服务端项目都应该包含有这两个文件,而且要放在相同的包名下。
客户端代码:
//MainActivity.java
package com.xxx.cn.client;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
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;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
class Listener extends IListener.Stub {
@Override
public void onChange(int x) throws RemoteException {
Log.i(TAG, "服务端回调了方法onChange,x = " + x);
}
}
private IManager manager;
private Listener mListener = new Listener();
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "onServiceConnected");
//得到本地代理对象
manager = IManager.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void bindService(View view) {
Log.i(TAG, "bindService");
Intent intent = new Intent("com.bindservice.MyService");
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
public void unbindService(View view) {
unbindService(connection);
}
public void caculate(View view){
if (manager == null) {
Log.i(TAG, "请绑定服务");
} else {
int result = 0;
try {
result = manager.add(4, 5);
} catch (Exception e) {
e.printStackTrace();
}
Log.i(TAG, "result=" + result);
}
}
public void listener(View view){
if (manager == null) {
Log.i(TAG, "请绑定服务");
} else {
try {
manager.registerListener(mListener);
Log.i(TAG, "注册监听");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void passPerson(View view) {
Person person = new Person();
person.setName("Mirhanana");
person.setSex(0);
if (manager == null) {
Log.i(TAG, "请绑定服务");
} else {
try {
manager.passPerson(person);
Log.i(TAG, "传递Person");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
客户端布局文件activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<Button
android:text="绑定服务"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="bindService"/>
<Button
android:text="解绑服务"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="unbindService"/>
<Button
android:text="计算"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="caculate"/>
<Button
android:text="传递监听"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="listener"/>
<Button
android:text="传递Person"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="passPerson"/>
</LinearLayout>
服务端代码:
//MyService.java
package com.xxx.cn.client;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "MyService";
private IListener mListener;
private Manager manager = new Manager();
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return manager;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
super.onDestroy();
}
class Manager extends IManager.Stub{
@Override
public int add(int x, int y) throws RemoteException {
return x + y;
}
@Override
public void registerListener(IListener listener) throws RemoteException {
mListener = listener;
//得到这个listner后,就可以在需要的地方回调客户端的onChange函数
mListener.onChange(4);
Log.i(TAG, "onChange");
}
@Override
public void passPerson(Person person) throws RemoteException {
String name = person.getName();
int sex = person.getSex();
Log.i(TAG,"姓名:" + name);
Log.i(TAG,"性别:" + (sex == 0 ? "女" : "男"));
}
}
}
先运行服务端,然后运行客户端,客户端运行界面如下:
点点击绑定服务之后,接着点击passPerson按钮。
客户端Log打印如下:
服务端Log打印如下:
可以看到我们客户端创建的Person对象确实传递到了服务端。
参考文章: