Android中跨进程通信的方式主要有以下几种方式:
1、通过Intent实现跨进程。这种方式主要是通过意图去激活安卓组件的方式来实现跨进程的通信,比如调用系统相机的功能就是通过意图去激活的。(单向)
2、通过content provider实现跨进程。这种方式主要是通过对外提供接口来实现数据共享的机制。(单向)
3、通过Messenger实现进程通信。这种方式主要通过IBinder和Handler机制实现的,可以看做AIDL的简单封装应用,优点是实现简单、不需要处理线程安全等问题,不足之处就是只能是串行的,不合适多并发的情形。(双向)
3.1 首先创建服务端Service,代码如下:
//GuoqiangService.java
package com.example.aidl.server;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
/**
* 创建一个服务
* @author zgq
*
*/
public class GuoqiangService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mMessenger.getBinder();
}
/**
* 用于接受消息
*/
private static final Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
//获取客户端发送的消息
Bundle bundle= msg.getData();
String c2s=bundle.getString("c-s");
System.out.println(c2s);
Log.d("c2s",c2s);
//服务端发送消息给客户端
Bundle data = new Bundle();
data.putString("s-c", "服务端向客户端发送的消息");
Messenger messenger= msg.replyTo;
Message message=Message.obtain();
message.setData(data);
try {
messenger.send(message);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
};
//创建Messager,用于进程间的通新
private static final Messenger mMessenger=new Messenger(handler);
}
3.2 创建客户端MessengerClient.java,代码如下:
//MessengerClient.java
package com.example.aidl.client;
import com.example.aidl.server.GuoqiangService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
/**
* 客户端
*
* @author zgq
*
*/
public class MessengerClient {
private MyServiceConnection mServiceConnection;
public MessengerClient() {
mServiceConnection = new MyServiceConnection();
}
/**
* 创建服务连接类
*
* @author zgq
*
*/
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
Messenger messenger = new Messenger(service);
Message message = Message.obtain();
try {
// 将客户端的messenger对象传递给服务端
message.replyTo = mMessenger;
// 发送消息(client->server)
Bundle data = new Bundle();
data.putString("c-s", "客户端向服务端发送的消息");
message.setData(data);
messenger.send(message);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
/**
* 启动服务
*
* @param context
*/
public void startService(Context context) {
Intent intent = new Intent(context, GuoqiangService.class);
context.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
/**
* 停止服务
*
* @param context
*/
public void stopService(Context context) {
context.unbindService(mServiceConnection);
}
/**
* 客户端接受消息用
*/
private static final Handler handler = new Handler() {
public void handleMessage(Message msg) {
// 获取服务端发送的消息
Bundle bundle = msg.getData();
String s2c = bundle.getString("s-c");
System.out.println(s2c);
Log.d("s2c", s2c);
};
};
/**
* 客户端创建Messenger对象
*/
private static final Messenger mMessenger = new Messenger(handler);
}
3.3 在清单文件中注册服务,代码如下:
<service
android:name=".server.GuoqiangService"
android:process=":guoqiang" >
</service>
3.4 调用方式主要分为同一个应用跨进程通信,这种方式只要想普通的服务启动即可;另一种情形是不同应用间的跨进程通信,这时就需要通过隐式意图的方式去激活Service,进而实现进程间的通信。
4、通过AIDL的方式实现进程通信。这种方式也是通过IBinder机制实现的,对外提供统一接口;优点是可是可以处理高并发的任务,缺点是需要控制好线程安全等问题。(双向)
4.1 创建服务端AIDLService,代码如下:
//AIDLService.java
package com.example.aidl.server;
import aidl.aidl.IPerson;
import aidl.aidl.Person;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
public class AIDLService extends Service {
/**
* 创建Binder对象
*/
private Binder mBinder = new IPerson.Stub() {
@Override
public Person getPerson() throws RemoteException {
// TODO Auto-generated method stub
synchronized (this) {
Person person=new Person();
person.setAge(22);
person.setName("server");;
return person;
}
}
@Override
public void setPerson(Person person) throws RemoteException {
// TODO Auto-generated method stub
synchronized(this){
//获取客户端传过来的值
Log.d("name",person.getName());
Log.d("age",person.getAge()+"");
}
}
};
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mBinder;
}
}
4.2 创建AIDL文件,主要包括定义接口类型的aidl文件(如IPerson.aidl)和定义进程间通信数据传输实体类(如Person.aidl),代码如下:
//IPerson.aidl
package aidl.aidl;
import aidl.aidl.Person;
interface IPerson {
Person getPerson();
void setPerson(in Person person);
}
//Person.aidl
package aidl.aidl;
parcelable Person;
此外Person.aidl必须有个Person.java文件与之对应,处理相关实现,代码如下:
//Person.java
package aidl.aidl;
import android.os.Parcel;
import android.os.Parcelable;
/**
* 用于进程间通信数据传输的jave bean
* @author zgq
*
*/
public class Person implements Parcelable {
private String name;
private int age;
public Person() {
}
public Person(Parcel in) {
// TODO Auto-generated constructor stub
this.name=in.readString();
this.age=in.readInt();
}
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 int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
dest.writeString(this.name);
dest.writeInt(this.age);
}
// 默认实现Parcelable的模版只支持in ,如果需要需要支持out或inout需要手动实现readFromParcel方法
public void readFromParcel(Parcel dest) {
// 注意,这里的读取顺序要writeToParcel()方法中的写入顺序一样
this.name = dest.readString();
this.age = dest.readInt();
}
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];
}
};
}
4.3 创建客户端,代码如下:
//AIDLClient.java
package com.example.aidl.client;
import aidl.aidl.IPerson;
import aidl.aidl.Person;
import com.example.aidl.server.AIDLService;
import com.example.aidl.server.GuoqiangService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
/**
* 客户端
*
* @author zgq
*
*/
public class AIDLClient {
private MyServiceConnection mServiceConnection;
public AIDLClient() {
mServiceConnection = new MyServiceConnection();
}
/**
* 创建服务连接类
*
* @author zgq
*
*/
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
IPerson iPerson = IPerson.Stub.asInterface(service);
try {
// 传值给服务端
Person person = new Person();
person.setAge(26);
person.setName("client");
iPerson.setPerson(person);
// 获取服务端的值
Person person2 = iPerson.getPerson();
Log.d("name", person2.getName());
Log.d("age", person2.getAge() + "");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
/**
* 启动服务
*
* @param context
*/
public void startService(Context context) {
Intent intent = new Intent(context, AIDLService.class);
context.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
/**
* 停止服务
*
* @param context
*/
public void stopService(Context context) {
context.unbindService(mServiceConnection);
}
}
4.4 启动服务,与3.4类似,不在阐述。
思路来源:
http://blog.csdn.net/luoyanglizi/article/details/51980630
http://blog.csdn.net/yulyu/article/details/56676262