Learn && Live
虚度年华浮萍于世,勤学善思至死不渝
前言
Hey,欢迎阅读Connor学Android系列,这个系列记录了我的Android原理知识学习、复盘过程,欢迎各位大佬阅读斧正!原创不易,转载请注明出处:http://t.csdn.cn/4U7jo,话不多说我们马上开始!
1.Bundle
(1)Bundle实现了Parcelable接口,因此可以在进程之间传输
(2)四大组件中的三大组件(Activity、Service、Receiver)都支持在Intent中传递Bundle数据,传输的数据必须能够被序列化,即基本类型、实现了Serializable或Parcelable接口的对象以及一些Android支持的特殊对象
2.文件共享
通过文件共享方式来共享数据对文件格式是没有具体要求的,只要读/写双方约定数据格式即可
(1)方式一:通过读/写同一个文件来交换数据,Android系统基于Linux,可并发读/写文件,甚至是同时写同一个文件
(2)方式二:一个进程序列化一个对象到文件系统中的同时从另一个进程回复这个对象,序列化的过程不再赘述
(3)并发读/写、并发写可能会导致读出的内容与真实情况不一致,应尽量避免或考虑使用线程同步来限制并发,该方法适合在对数据同步要求不高的进程之间进行通信,并且要妥善处理并发问题
SharedPreferences
(1)Android轻量级存储方案,通过键值对存储数据,底层采用XML存储,SharedPreferences文件目录位于/data/data/<PackageName>/shared_prefs
(2)SharedPreferences本质上也是一种文件,但系统对它的读/写有一定的缓存策略,即在内存中有一份SharedPreferences文件的缓存,因此在多进程模式下,系统对它的读/写就变得不可靠,高并发访问可能会导致丢失数据,因此不建议在进程间通信时使用
3.Messenger
信使,通过它可以在进程间传递包含数据的Message对象,底层实现是AIDL,看看它的两个构造方法就很明了了
public Messenger(Handler handler) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
下面介绍Messenger的实现步骤,由于它一次处理一个请求,因此在服务端不需要考虑线程同步问题
服务端进程
(1)创建一个Service来处理客户端请求,同时创建Handler
(2)通过Handler对象创建一个Messenger对象
(3)在onBind中返回Messenger对象底层的Binder
// (1)
public class MessengerService extends Service {
private static class MessengerHandler extends Handler {
@override
public void handleMessage(Message msg) {
switch(msg.what) {
case MyConstants.MSG_FROM_CLIENT:
// 客户端(3)
Messenger client = msg.replyTo;
Message replyMessage = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);
Bundle bundle = new Bundle();
bundle.putString("reply", "reply");
replyMessage.setData(bundle);
try {
client.send(replyMessage);
} catch(RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
// (2)
private final Messenger mMessenger = new Messenger(new MessengerHandler());
// (3)
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
客户端进程
(1)绑定服务端的Service,用服务端的IBinder对象创建一个Messenger,即可通过它向服务端发送Message消息
(2)创建一个Handler并创建一个新的Messenger
(3)将这个Messenger对象通过Message的replyTo参数传递给服务端,服务端通过replyTo参数即可回应客户端
public class MessengerActivity extends Activity {
private Messenger mService;
// (2)
private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case MyConstants.MSG_FROM_CLIENT:
getString("reply");
break;
default:
super.handleMessage(msg);
}
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mService = new Messenger(service);
Message msg = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg", "hello");
msg.setData(data);
// (3)
msg.replyTo = mGetReplyMessenger;
try {
mService.send(msg);
} catch(RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
Intent intent = new Intent(this, MessengerService.class);
// (1)
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(mConnection);
super.onDestroy();
}
}
Messenger工作原理
结合上述的步骤和具体的代码,可以总结出下图的工作原理
局限性
Messenger以串行的方式处理客户端发来的消息,如果大量的消息同时发送到服务端,服务端依然只能一个一个处理,不适合高并发场景