一. IPC全称Inter-Process Communication ,进程间通信。IPC 的具体方式有很多,比如可以通过Intent,共享文件,还可以采用Binder方式来夸进程访问,此外,通过网络通信也可以实现数据传递,所以Socket也可以实现IPC 。上述各个方式都有较大的差别。
二. 具体方式:
2.1 使用Bundle :
我们知道四大组件中的三大组件(Activity , Service , Receiver)都支持在Intent中传递Bundle数据,由于Bundle实现了Parcelable接口,所以它可以方便地在不同进程中传递。当然,我们传递的数据必须能被序列化。
2.2使用文件共享:
共享文件是一种不错的进程间通信方式,两个进程通过读写同一个文件来交换数据,比如A进程将数据写入文件中,B进程通过读取这个文件来获取数据。
SharePreferences是个特例,它是Android中提供的轻量级的存储方案,它通过键值对的方式来存储数据,在底层上它是采用XML文件来存储键值对的,每个应用的SharePrefrences文件都可以在当前包名所在的data目录下查到。一般位于/data/data/package name /shared_prefs目录下。从本质上讲,SharePreferences也是一种文件,但是由于系统对它有一定的缓存策略,即在内存中也会有一份SharePreferences文件的缓存。因此在多进程中,系统对它的读写就变得不在可靠了,而且在并发时可能会出现数据丢失的情况。所以,不建议在进程中使用SharePreferences。
2.3 使用Messenger:
Messenger可以翻译为信使,顾名思义,通过它可以在不同进程中传递Messenger对象,在Messenger中放入我们需要传递的数据,这样就可以实现进程间的数据传递了。Messenger是一个轻量级的IPC方案,它低层是是实现了AIDL。
Messenger的使用方法:由于它一次处理一个请求,因此在服务端我们不用考虑线程同步问题。
2.3.1 服务端进程:
首先,我们需要在服务端创建一个Service来处理客户端的链接请求,同时创建一个Handler 并通过它来创建一个Messenger对象,然后在Service的onBind中返回这个Messenger对象低层的Binder即可。
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
public final Messenger mMessenger = new Messenger(new MessengerHandler());
public MessengerService() {
}
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MessengerConstants.ONE:
Log.d(TAG, "get data from Client " + msg.getData().get("key"));
break;
case MessengerConstants.TWO:
Log.d(TAG, "get data from Client " + msg.getData().get("key"));
break;
default:
break;
}
}
}
}
2.3.2 客户端进程:
客户端首先要绑定服务端的Service,绑定成功了用服务端返回的IBinder对象创建一个Messenger,通过这个Messenger就可以向服务端发送消息了。发送的消息是Messenger对象。如果需要服务端能够回复用户端,就和服务端一样,我们还需要创建一个Handler并创建一个Messenger,并把这个Messenger对象通过Message的replyTo参数传递给服务端,服务端通过这个replyTo参数(Messenger)就可以回应客户端。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Messenger mServiceMessenger;
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mServiceMessenger = new Messenger(service);
Message message = Message.obtain(null, MessengerConstants.ONE);
Bundle bundle = new Bundle();
bundle.putString("key", "hello ! I am Client");
message.setData(bundle);
try {
mServiceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("-----", TAG + " " + "onServiceDisconnected");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(mServiceConnection);
super.onDestroy();
}
}
2.4 使用AIDl :
2.5 使用Socket