Android实现跨进程接口回掉的方法
前言
同一个进程内实现接口回掉很简单,这里不做叙述,本文主要讲的是跨进程的接口回掉实现方式。有一种跨进程通信的方式就是使用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对象方法
//其实remotecallbacklist类似于java中{@link java.util.observable},用来批量处理接口回调对象, //其实如果确保只有一个客户端会bind到这个服务,只需要保存一个imyaidlinterfacecallback即可。 //但是如果有多个,强烈推荐使用其实remotecallbacklist 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(); } } //结束后一定要使用finsh,否则下次执行beginbroadcast会抛出illegalstateexception异常 mcallbacks.finishbroadcast(); }
在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(); } } }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
下一篇: iOS实现短信验证码倒计时