进程间复杂数据类型传递涉及服务端和客户端
1. 服务端
1> 目录结构
2> 传递的数据类Person
package com.zhangchao.aidl;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable {
private String name;
private int sex;
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
return new Person(source);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
public Person() {
}
public Person(Parcel source) {
readFormParcel(source);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
dest.writeInt(this.sex);
}
public void readFormParcel(Parcel source) {
this.name = source.readString();
this.sex = source.readInt();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
3> Person.aidl文件
package com.zhangchao.aidl;
parcelable Person;
4> IGreetService.aidl
package com.zhangchao.aidl;
import com.zhangchao.aidl.Person;
interface IGreetService{
String greet(in Person person);
}
5> AIDLService实现类
package com.zhangchao.ipcserver;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.zhangchao.aidl.IGreetService;
import com.zhangchao.aidl.Person;
public class AIDLService extends Service {
private static final String TAG = "AIDLService";
IGreetService.Stub stub = new IGreetService.Stub() {
@Override
public String greet(Person person) throws RemoteException {
Log.i(TAG, "greet(Person person) called");
String greeting = "hello" + person.getName();
switch(person.getSex()) {
case 0:
greeting = greeting + " , you're handsome.";
break;
case 1:
greeting = greeting + " , you're beautiful.";
break;
}
return greeting;
}
};
@Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "onBind() called");
return stub;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind() called");
return true;
}
}
6> 在AndroidManifest.xml中注册服务
<service
android:name=".AIDLService">
<intent-filter >
<action android:name="com.zhangchao.ipcserver.AIDLService"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
2. 客户端
1> 目录结构
2> Person.java, Person.aidl, IGreetService.aidl直接从服务端连同包一起复制到客户端
3> 客户端实现类
package com.zhangchao.ipcclient;
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.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.zhangchao.aidl.IGreetService;
import com.zhangchao.aidl.Person;
public class MainActivity extends Activity implements OnClickListener {
private Button btBind;
private Button btUnbind;
private Button btGreet;
private IGreetService mService = null;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("ServiceConnection", "onServiceDisconnected() called");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("ServiceConnection", "onServiceConnected() called");
mService = IGreetService.Stub.asInterface(service);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btBind = (Button) findViewById(R.id.bind);
btBind.setOnClickListener(this);
btUnbind = (Button) findViewById(R.id.unbind);
btUnbind.setOnClickListener(this);
btGreet = (Button) findViewById(R.id.greet);
btGreet.setOnClickListener(this);
btBind.setEnabled(true);
btUnbind.setEnabled(false);
btGreet.setEnabled(false);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bind:
bindService(new Intent("com.zhangchao.ipcserver.AIDLService"),
conn, Context.BIND_AUTO_CREATE);
btBind.setEnabled(false);
btUnbind.setEnabled(true);
btGreet.setEnabled(true);
break;
case R.id.unbind:
unbindService(conn);
btBind.setEnabled(true);
btUnbind.setEnabled(false);
btGreet.setEnabled(false);
break;
case R.id.greet:
Person person = new Person();
person.setName("zhangchao");
person.setSex(0);
try {
String retValue = mService.greet(person);
Toast.makeText(this, retValue, Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
Toast.makeText(this, "error", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
以上就实现了进程间复杂数据类型的传递,实现步骤总如下:
服务端:
1. 先实现需要传递的数据类,该类必须实现Parcelable接口;
2. 编写.aidl文件(eclipse会自动在gen目下生成对应的.java);
3. 编写服务类,继承Service,覆写onBind/onUnbind方法,同时实例化AIDL对应的静态子类Stub;
4. 在AndroidManifest.xml中注册服务;
客户端:
1. 将服务端中的数据类以及.aidl连同包一起复制;
2. 实现调用类
1> 实例化ServiceConnection对象;
2> 覆写onServiceDisconnected/onServiceConnected方法,在onServiceConnected方法中调用Stub中的asInterface获取服务;
3> 通过bindService绑定服务;
4> 通过获取到的服务调用远程方法,实现进程间通讯;