在android开发中一个App很少情况下是只具备一个进程的,因此多个进程存活在同一个App中非常正常,这对减少app的pss也很有帮助。出现多个进程,也不得不谈及跨进程通信,目前主要有以下几种跨进程通信方式:
1.Bundle方式,该方式一般用于Service,Activity,BroadcastReceiver组件间通信,当进程A的ActivityA,想传个东西给进程B的ActivityB,此时就可以采用Bundle方式传递,但是有个前提就是Bundle支持的数据类型有限,有时候需要对数据进行Parcelable或Serializable;但有时候你觉得序列化很麻烦,IntentService策略也是一种选择,将获取ActivityB所要用到的数据处理逻辑让IntentService来处理,而IntentService也设置在进程B中,这样在ActivityA中启动下IntentService,结果马上就出来了。
2.文件共享,该方法简单,但是并不适合高并发场景,尽管在android中多个进程对文件进行读写没有报错,但是获取数据可能存在问题,对并发访问实时性不是很高的,可以考虑下这种方法;
3.Messenger方式,注意不是Message,该方式尽管底层逻辑也是AIDL模式,功能一般,对高并发情景处理也不是很乐观,当你需要服务器和客户端交换些数据时,可以考虑下这种方法;
4.ContentProvider,这本就是android的组件,效率也不要考虑,不过也可以看成是约束性AIDL,主要提供CRUD操作,支持一对多进程间通信;
5.Socket,有个网络经验的自然不会陌生,但其实现细节有点繁琐,也可以适用于网络数据交换;
6.SharedPreference,这个东西尽管大家经常用,但他不适合跨进程传递数据,如果喜欢它了,用ContentProvider改造下即可,重点实现getType方法。
7.AIDL, 这位大神终于出来了,这无疑是大家首先想到的跨进程方式,采用它,客户端只要bind上服务端,就可以调用服务端提供的功能,其实呢,通过各接口,服务端还是可以主动调用客户端方法
具体细节见代码:
package com.example.testservice; import com.example.testservice.ITestCallback; interface test { int getBookId(); void setCallBack(ITestCallback callback); } package com.example.testservice; interface ITestCallback { void addName(String name); }
客户端绑定逻辑:
<pre name="code" class="html">private DeathRecipient mDeathRecipient = new DeathRecipient() { @Override public void binderDied() { if(idTest != null){ idTest.asBinder().unlinkToDeath(mDeathRecipient, 0); idTest = null; // bindServiceImpl(); } } }; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { //ignore } @Override public void onServiceConnected(ComponentName name, IBinder service) { idTest = test.Stub.asInterface(service); setCallBack(); try { idTest.asBinder().linkToDeath(mDeathRecipient, 0); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; private void setCallBack(){ try { idTest.setCallBack(new ITestCallback.Stub() { @Override public void addName(String name) throws RemoteException { } }); } catch (RemoteException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } }