Android查缺补漏(IPC篇)-- Bundle、文件共享、ContentProvider、Messenger四种进程间通讯介绍

进程间通讯篇系列文章目录:

Android查缺补漏(IPC篇)-- 进程间通讯基础知识热身

Android查缺补漏(IPC篇)-- Bundle、文件共享、ContentProvider、Messenger四种进程间通讯介绍

Android查缺补漏(IPC篇)-- 款进程通讯之AIDL详解

Android查缺补漏(IPC篇)-- 跨进程通讯之Socket简介及示例

在Android中进程间通信的实现方式有多种,包括:Bundle、文件共享、ContentProvider、Messenger、AIDL、Socket等等,其各有各的优缺点,接下来就分别介绍一下上述各种进程间的通信方式及实现。

一、Bundle

Activity、Service、Receiver都支持Intent中传递Bundle数据,由于Bundle实现了Parcelable接口,所以它可以方便的在不同的进程间传输。

传输的数据必须能够被序列化:

基本类型

String类型

CharSequence

实现了Parcelable接口的对象

实现了Serializable接口的对象

List

IBinder类型

SparseArray

二、文件共享

文件共享作为进程间通讯时,无法解决并发读写时所带来的问题,所以只适合在对数据同步要求不高的进程间通讯。

其实SharedPreferences也属于文件共享方式的一种,sp是android中提供的一种轻量级存储方案,通过键值对的方式来存储数据,底层用xml文件来存储键值对。每个应用的sp文件放在当前包所在的data目录下,位于/data/data/package_name/shared_prefs目录下。由于系统对它的读写有一定的缓存策略,即在内存中会有一份sp文件的缓存,因此在多进程模式下,它变得不可靠。

三、ContentProvider

ContentProvider在前面介绍四大组件时就已经介绍过了,这里就不多说了,详见《Android查缺补漏--ContentProvider的使用》

四、Messenger 1、Messenger是什么?

通过Messenger可以很方便的在不同的进程之间传递Messager对象,在Messager对象中就可以放入我们需要传递的数据。我们知道,跨进程传输数据有很多种方式,其中AIDL最为强大也最为常用,而Messenger即相当于AIDL的简化版,其底层也是采用AIDL实现,是一种轻量级的跨进程传输方案。

所谓简化版常常功能有限,Messenger也不例外,相对于AIDL它的功能确实弱化了不少,在方便使用的同时它一次只能处理一个请求。

2、实现一个简单的Messenger通讯

实现一个Messenger需要在两个进程中做以下操作:

为了避免歧义,我们提前约定,以下所说的服务端若不做特别说明默认指Service所在的进程。

在服务端:首先,创建一个Service充当服务端进程,然后在Service中创建一个Messenger,因为创建Messenger时需要传入一个Handler,所以还要创建一个Handler,接收数据的操作就在Handler中,最后在Service的onBind中返回这个Messenger的Binder即可。

示例代码如下:

/** * Created by liuwei on 18/1/29. */ public class MessengerService extends Service { private static final String TAG = MessengerHandler.class.getSimpleName(); // 创建一个Handler,处理消息用 private class MessengerHandler extends Handler{ @Override public void handleMessage(Message msg) { switch (msg.what) { case AppConstants.MSG_FROM_CLIENT: // 接收客户端发来的消息 Log.i(TAG, "handleMessage: MSG_FROM_CLIENT:" + msg.getData().getString("msg")); break; default: super.handleMessage(msg); } } } // 创建Messenger private Messenger messenger = new Messenger(new MessengerHandler()); @Nullable @Override public IBinder onBind(Intent intent) { // 返回Messenger的Binder return messenger.getBinder(); } }

这里要想让Service跑在另外一个进程中需要在AndroidManifest文件中添加process节点:

<service android:name=".messager.MessengerService" android:process=":remote" />

在客户端:就像绑定一个普通的Service一样,通过bindService方法链接Service即可,不同点是,需要在ServiceConnection接口中的onServiceConnected方法中通过参数中的IBinder创建一个Messenger对象,通过这个Messenger对象即可向服务端发送message消息。

示例代码如下:

public class MessengerActivity extends AppCompatActivity { private final static String TAG = MessengerActivity.class.getSimpleName(); Button btn_bind_messenger; Intent intent; Messenger messenger; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_messenger); btn_bind_messenger = ViewUtils.findAndOnClick(this, R.id.btn_bind_messenger, mOnClickListener); intent = new Intent(this, MessengerService.class); } private View.OnClickListener mOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_bind_messenger: // 绑定Service bindService(intent, connection, BIND_AUTO_CREATE); break; } } }; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 链接messenger成功,利用service创建一个Messenger messenger = new Messenger(service); // 向服务端发送一条消息 Message message = Message.obtain(null, AppConstants.MSG_FROM_CLIENT); Bundle bundle = new Bundle(); bundle.putString("msg", "client bind messenger succeed!"); message.setData(bundle); try { messenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { messenger = null; } }; @Override protected void onDestroy() { unbindService(connection); super.onDestroy(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfdzz.html