使用AIDL传递自定义Bean结构,必须实现parcelable接口
// Parcelable与Serializable序列化对比
// 1.在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
//
// 2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
//
// 3.Parcelable不能使用在要将数据存储在磁盘上的情况,
// 因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。
// 尽管Serializable效率低点,但此时还是建议使用Serializable 。
public class User implements Parcelable {
private String userName;
private String passwd;
public User() {
}
public User(String userName, String passwd) {
this.userName = userName;
this.passwd = passwd;
}
protected User(Parcel in) {
userName = in.readString();
passwd = in.readString();
}
//为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例
public static final Creator CREATOR = new Creator() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
// 内容描述方法,基本不用
@Override
public int describeContents() {
return 0;
}
// 写入接口函数,打包
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(userName);
dest.writeString(passwd);
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", passwd='" + passwd + '\'' +
'}';
}
}
// IGetUser.aidl
package cn.edu.hebust.aidldemo2;
// Declare any non-default types here with import statements
// 手动添加
import cn.edu.hebust.aidldemo2.User;
interface IGetUser {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
// 自定义的AIDL接口
List getUserInfo(String name);
}
这里必须定义AIDL Bean文件,不然会出现import error 的编译错误,将AIDL声明Bean结构即可
// IUser.aidl
package cn.edu.hebust.aidldemo2;
// Declare any non-default types here with import statements
import cn.edu.hebust.aidldemo2.User;
parcelable User;
这时会生成相应的Java文件, 然后使用这个java文件进行通信
提供一个Service供通信
public class MyService extends Service {
// 实际的通信对象
private IBinder mStub = new IGetUser.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
// 与其他Client通信的接口
@Override
public List getUserInfo(String name) throws RemoteException {
List list = new LinkedList<>();
for (int i = 0; i < 10; i++) {
list.add(new User(name + i, name + (i >> 2)));
}
return list;
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mStub;
}
}
拷贝相同的aidl文件和bean文件
注意Bean文件的包名应该一样
// 另一个进程中的通信代码,通过Service
public class MainActivity extends AppCompatActivity {
private static final String TAG = "LOGGER";
private TextView mTvText;
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IGetUser mStub = IGetUser.Stub.asInterface(service);
try {
List list = mStub.getUserInfo("terry");
for (User aUser : list) {
mTvText.append(aUser.toString() + "\n");
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected: ");
Toast.makeText(MainActivity.this, "onServiceDisconnected", Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTvText = (TextView) findViewById(R.id.id_tv_text);
Intent intent = new Intent();
ComponentName componentName = new ComponentName("cn.edu.hebust.aidldemo2"
, "cn.edu.hebust.aidldemo2.MyService");
intent.setComponent(componentName);
bindService(intent, mConn, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(mConn);
super.onDestroy();
}
}