跨进程通信的方式
1.通过Intent中附加extras来传递信息。
2.通过共享文件的方式来共享数据。
3.通过Binder方式来跨进程通信。
4.ContentProvider本身就是支持跨进程通信的。
5.此外网络通信也是可以实现传递数据的,所以Socket也可以实现IPC。
.
.
使用Bundle
四大组件中有三大组件(Activity、Service、Receiver)是支持在Intent中传递Bundle数据的。Bundle实现了Parcelable接口,所以它可以方便的在不同进程间传输。在Bundle中添加的数据可以是基本数据类型、实现了Parcelable或Serializable接口的对象以及Android支持的特殊对象。
.
.
使用文件共享
共享文件是一种不错的进程间通信方式,两个进程通过读/写同一个文件来进行交换数据。由于Android系统是基于Linux的,使得其并发读/写文件可以没有任何限制地进行,甚至两个线程同时对同一个文件进行写操作都是被充许的,尽管这可能出问题。除了可以交换一些文本信息外,还可以序列化一个对象到文件系统中的同时从另一个进程中恢复这个对象。
注意:如果并发读/写,我们读取出来的数据可能不是最新的,如果是并发写的话那就更严重了,因此我们要尽量避免并发写这种情况的发生或者考虑使用线程同步来限制多个线程的写操作。文件共享方式适合在对数据同步要求不高的情况的进程之间进行通信,并且要妥善处理并发读/写的问题。
SharedPreferences是Android中轻量级的存储方案,通过键值对的方来存储数据。从本质来说,SharedPreferences也是属于文件的一种,但是系统对于它的读/写有一定的缓存策略,即在内存中有一份SharedPreferences文件的缓存,因此在多进程模式下,系统对它的读/写变得不可靠,面对高并发的读/写访问有很大几率会丢失数据。不建议在进程间通信中使用SharedPreferences。
.
.
使用Messenger
通过使用Messenger传递Message对象,在Message中放入我们需要传递的数据。就可以轻松实现数据的进程间传递。Messenger是一种轻量级的IPC方案,其底层实现是AIDL。其在源代码中的构造方法中可得知。
.
它一次只能处理一个请求,因此在服务端我们无需考虑线程同步的问题。
实现Messenger有如下几个步骤,分为服务端和客户端。
1.服务端
首先需要创建一个Service来处理客户端的连接请求,同时创建一个Handler并通过它来创建一个Messenger对象,然后在Service的onBind中返回这个Messenger对象底层的Binder对象。
2.客户端
首先需要绑定服务端Service,绑定成功后用服务端返回的IBinder对象创建一个Messenger,通过这个Messenger就可以向服务端发送消息了,发送消息的类型是Message。如果需要服务端回复客户端,客户端就和服务端一样,创建一个Handler并创建一个Messenger对象,使用在发送给服务端的Message.replyTo指定为客户端的Messenger对象。
Message和Messenger都是实现了Parcelable接口的,因此可以跨进程传输。Message中能使用的载体只有what,age1,age2,Bundle以及replyTo。另外还有object,但这个参数对于在同一个进程中是很实用的,但是在多进程中(2.2以前是不支持跨进程传输的,2.2以后也是也只是支持系统实现了Parcelable的对象)。
下面是演示代码:
package com.thh.ipcdemo2.messenger;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.thh.ipcdemo2.R;
public class MessengerActivity extends AppCompatActivity {
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("thhi","[MessengerActivity ServiceConnection onServiceConnected]");
Messenger messenger = new Messenger(service);
Message message = Message.obtain(null, MessengerService.MSG_FROM_CLIENT);
Bundle bundle = new Bundle();
bundle.putString("msg","你好! 我是客户端");
message.setData(bundle);
message.replyTo = mMessenger;
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("thhi","[MessengerActivity ServiceConnection onServiceDisconnected]");
}
};
private static class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MessengerService.MSG_FROM_SERVICE:
String content = msg.getData().getString("msg");
Log.i("thhi","[MessengerActivity MessengerHandler handleMessage]"+content);
break;
default:
super.handleMessage(msg);
break;
}
}
}
private Messenger mMessenger = new Messenger(new MessengerHandler());
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
}
}
package com.thh.ipcdemo2.messenger;
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.support.annotation.Nullable;
import android.util.Log;
/**
* Created by TangHui on 2015/10/14.
*/
public class MessengerService extends Service {
public static final int MSG_FROM_CLIENT = 1000;
public static final int MSG_FROM_SERVICE = 1001;
private class MessageHandler extends Handler{
@Override
public void handleMessage(Message msg) {
Log.i("thhi","[MessengerService MessageHandler handleMessage]");
switch (msg.what){
case MSG_FROM_CLIENT:
String content = msg.getData().getString("msg");
Log.i("thhi","[MessengerService MessageHandler handleMessage] content:"+content);
Messenger replyTo = msg.replyTo;
Message message = Message.obtain(null, MSG_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("msg","这是服务端,已经成功收到你的消息!");
message.setData(bundle);
try {
replyTo.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}
private final Messenger mMessenger = new Messenger(new MessageHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i("thhi","[MessengerService onBind]");
return mMessenger.getBinder();
}
}