时间:2021-05-19
前言
同一个进程内实现接口回掉很简单,这里不做叙述,本文主要讲的是跨进程的接口回掉实现方式。有一种跨进程通信的方式就是使用AIDL,但是单纯的AIDL通信只可以实现客户端访问服务端主动获取Binder对象,如果服务端有变化无法及时通知客户端。现在可以通过AIDL跨进程接口回掉来解决服务端发生变化通知客户端的问题。
谷歌提供了RemoteCallbackList来实现对IInterface的管理。public class RemoteCallbackList<E extends IInterface>
首先定义两个AIDL文件:
1.ITestCallBack.aidl
interface ITestCallBack { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void onTagValid(in String tag);}2.ITestInterface.aidl 在注册和反祖册方法中,需要传入ITestCallBack的对象
interface ITestInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ boolean isTagValid(in String tag); void registerCallback(in String tag, in ITestCallBack callback); void unRegisterCallback(in String tag, in ITestCallBack callback);}服务端:
创建Service,并且在service中定义RemoteCallbackList集合,实现ITestInterface.Stub,在registerCallback,和unRegisterCallback中,分别将ITestCallBack对象注册和反注册进RemoteCallbackList中。RemoteCallbackList提供了获取注册进去的IInterface对象方法
在isTagValid中可以调用callBack方法去遍历注册的接口对象,也可以当服务端有变化时主动调用callBack方法去通知客户端,这样就实现了服务端变化主动通知客户端。可根据实际方法修改。
在service的onBind方法中,返回ITestInterface.Stub的对象即可,等待客户端绑定服务端。
下面是服务端Service的代码:
public class TestService extends Service { private RemoteCallbackList<ITestCallBack> mCallBacks = new RemoteCallbackList<>(); private String tag = "hy"; public TestService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return iTestInterface; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } ITestInterface.Stub iTestInterface = new ITestInterface.Stub() { @Override public boolean isTagValid(String tag) throws RemoteException { if (tag.equals(TestService.this.tag)) { callBack(); return true; } return false; } @Override public void registerCallback(String tag, ITestCallBack callback) throws RemoteException { if (null != mCallBacks && null != callback) { mCallBacks.register(callback); } } @Override public void unRegisterCallback(String tag, ITestCallBack callback) throws RemoteException { if (null != mCallBacks && null != callback) { mCallBacks.unregister(callback); } } }; public void callBack() { if (mCallBacks == null) { return; } int num = mCallBacks.beginBroadcast(); for (int i = 0; i < num; i++) { try { mCallBacks.getBroadcastItem(i).onTagValid("congratulation callback success " + tag); } catch (RemoteException e) { e.printStackTrace(); } } mCallBacks.finishBroadcast(); }}客户端:
客户端首先要做的是绑定服务端,实现AIDL的通信,在客户端创建绑定按钮,解绑按钮,和主动获取信息的通信按钮。在主动获取信息的通信按钮中实现iTestInterface对象的isTagValid方法可以主动去获取服务端的信息(服务端在isTagValid方法中调用了callBack方法)。
客户端代码:
public class MainActivity extends AppCompatActivity { private String tag = "hy"; private ITestInterface iTestInterface; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iTestInterface = ITestInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { iTestInterface = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindService(); ((Button) findViewById(R.id.buttonregister)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { iTestInterface.registerCallback(tag, new ITestCallBack.Stub() { @Override public void onTagValid(String tag) throws RemoteException { Log.e("test", "registerCallback: " + tag); } }); } catch (RemoteException e) { e.printStackTrace(); } } }); ((Button) findViewById(R.id.buttonunregister)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { iTestInterface.unRegisterCallback(tag, new ITestCallBack.Stub() { @Override public void onTagValid(String tag) throws RemoteException { } }); } catch (RemoteException e) { e.printStackTrace(); } } }); ((Button) findViewById(R.id.buttonisvalid)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { iTestInterface.isTagValid(tag); } catch (RemoteException e) { e.printStackTrace(); } } }); } private void bindService() { Intent intent = new Intent(); intent.setAction("com.example.heyang.myapplication.TestService"); intent.setPackage("com.example.heyang.myapplication"); boolean success = bindService(intent, connection, Context.BIND_AUTO_CREATE); if (success) { Log.e("test ", "bindService OK"); } else { Log.e("test ", "bindService Fail"); } } @Override protected void onDestroy() { super.onDestroy(); unBindeService(); } private void unBindeService() { try { unbindService(connection); } catch (Exception e) { e.printStackTrace(); } }}总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了Android编程实现AIDL(跨进程通信)的方法。分享给大家供大家参考,具体如下:一.概述:跨进程通信(AIDL),主要实现进程(应用)间数据共
在Android系统中,跨进程通信是非常普遍的事情,它用到了Binder机制处理进程之间的交互。Binder机制会开放一些接口给Java层,供android开发
AIDL是Android接口定义语言,它可以用于让某个Service与多个应用程序组件之间进行跨进程通信,从而可以实现多个应用程序共享同一个Service的功能
Android跨进程SharedPreferences异常详解Contextc=null;try{c=context.createPackageContext(
在Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?显然,Java中是不支持跨进程内存共享的。因此要传递对象