Android 进程间通信(三)——Bundle、Message、ContentProvider
在前面的文章Android进程间通信机制之AIDL中我们简单的介绍了AIDL的使用。在Android中我们还可以使用其他的进程间通信方式:
- 使用Bundle携带数据进行进程间的通信;
- 使用Message进行进程间的通信;
- 使用文件进行进程间的通信;
- 使用ContentProvider进行进程间的通信;
- …
我们可以看到要实现进程间的通信方式有很多种,下面我们就来介绍一下使用它们如何实现进程间的通信。
1、利用Bundle在进程间进行通信
Bundle通常与Intent在一起使用,它们也常用于Activity、Service和Receiver之间的数据传递。
那么为什么Bundle可以在进程间传递数据,因为Bundle实现了Parcelable接口,拥有了在进程间传递数据的能力。
public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
//......
}
它支持基本类型的数据和其他实现了Parcelable接口的对象的传递。在代码中使用它们:
在第一个Activity中:
Intent intent = new Intent(this,OtherProcessActivity.class);
Bundle extras = new Bundle();
extras.putString("test0", "string");
extras.putParcelable("parcelable", new Book(0, "bookName 0"));
intent.putExtras(extras);
startActivity(intent);
在跳转到的Activity中获取数据:
Intent intent = getIntent();
Bundle extras = intent.getExtras();
String extrasString = extras.getString("test0");
Book book = ((Book) extras.getParcelable("parcelable"));
Log.e("bundle", extrasString + " === " + book.toString());
如此,就完成了进程间数据的传递。
2、使用Messenger进行进程间的通信
Messenger即为信使,用来传递Message,Message是我们要传递的数据的载体。Messenger通过在不同的进程间传递Message就可以实现进程间的通信。
Messenger其实就是用AIDL来实现的,Messenger是对AIDL的封装,所以Messenger和AIDL其实是一样的。Google建议我们在Messenger和AIDL都可以使用的情况下优先使用Messenger,因为它使用起来更加便捷。
服务端
新建一个Service类,在内部创建一个Messenger对象,用来接收Client传递过来的信息,并在处理完信息后把结果反馈给Client。
服务端代码:
public class MessengerService extends Service {
@SuppressLint("HandlerLeak")
private Messenger mMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
//创建一个Message用于存放发送回Client的消息
Message sendToClientMsg = Message.obtain(msg);
switch (msg.what) {
case Constant.CLIENT_TO_SERVICE_WHAT:
try {
Bundle bundle = msg.getData();
bundle.setClassLoader(getClass().getClassLoader());
Log.e("debug", "从客户端来的消息:"+bundle.getParcelable("book").toString());
sendToClientMsg.what = Constant.SERVICE_TO_CLIENT_WHAT;
Bundle data = new Bundle();
data.putParcelable("bundle",new Book(1,"Service To Client book"));
sendToClientMsg.setData(data);
msg.replyTo.send(sendToClientMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
super.handleMessage(msg);
}
});
@Nullable
@Override
public IBinder onBind(In