设为首页 收藏本站
查看: 760|回复: 0

[经验分享] PC远程调用Android上的程序(RPC)

[复制链接]

尚未签到

发表于 2017-2-28 11:02:17 | 显示全部楼层 |阅读模式
  Author 正正 Date  2010.12.31 23:15:00   转载请注明出处 正正博客 http://www.2009fly.com
  最近做一个项目,需要用PC去调用Android上的程序实现某些操作。原来是利用PC来模拟Android上的工作过程,由于时间紧张,一直没有时间移植过去,当时也不知道Android上到底该怎么操作,接口是什么。到了产品的第二阶段,需要考虑移植的问题,但是这时候已经有很多的类全是按照在PC上写的,幸亏当时只是提供的接口。好了,废话少说,现在看看具体实现吧。
  Android做Server,一开始我考虑的是将WebService移植到Android上,至于Web容器,已有人将Jetty移植了过去,也就是i-jetty。但是这个太重量级了,而且要修改的东西会太多。比如PC上要实现WebService上的客户端操作,这个未免小题大做,况且只有很少的几个接口调用,于是我考虑自己写一个简单的RPC操作,下面是我的构思:
  PC(RPC Client)端发送一个RPCRequest,然后用socket通信方式发送到Android(RPC Server)上,Android解析RPCRequest,用反射机制完成相应类的调用,如果是第一次调用,并且传递的方法名和类的名称一样,则会初始化该类【构造函数调用】,并将类的实例在Server端注册,以便下次可以直接调用;如果是其他方法,则可以直接调用。将调用的结果构造成RPCResponse对象返回给PC(RPC  Client),这样就完成一次完整的RPC操作。需要注明的一点,就是socket传递的对象必须是可以序列化的,否则会出错的。(当然,这是很基础的事情,我只是提醒一下,因为很多时候你会忘记这么做!)
  现在的关键是RPCRequest和RPCResponse具体内容是什么?
  RPCRequest里面主要包括|RequestHead和RequestBody两个部分。其中,Head部分主要含有协议的版本信息,还有用于处理除实例方法调用外的其他事情,比如系统初始化、通知server释放注册的实例等等。Body部分包括类实例的唯一标识id、类的完全限定名、要调用的方法名、方法的参数类型表、参数的具体值。其中,id主要用来唯一的标识一个类的实例,我用的算法是类的完全限定名称和当前时间(1970年1月1日0:00至今的毫秒时间)的字符串组合,当然,你可以再进行一次摘要算法来保证准确性。类的完全限定名是指远程调用的类的名称,存在于RPCServer端,也就是这里的Android上。参数的类型和参数值,可以参考反射的知识,因为在RPCServer端要根据反射来调用相应的类。
  RPCResponse里面也包括两个部分,ResponseHead和ResponseBody。其中Head也包括协议的版本信息,初次之外就是功能部分,其主要是在RPCServer端调用实例方法出现异常错误的时候传递的execepiton信息。Body部分和RequestHead部分一样,只不过最后多了个返回的结果信息。
  除了上面两个类之外,你还要准备一个Handle接口,主要用来处理对上面RPCRequest、RPCResponse的具体解析,为了使RPC可以“跨平台”——指的是不只是针对pc和android,也可以是pc对pc,android对android。需要对打印信息进行封转,不过要记住,你先要判断你所在的平台,可以用System的getProperties方法,这个简单,就不用多讲了。
  下面是我给的RPCRequest,RPCResponse的定义,仅供参考:
  RPCRequest类的member及其类型:
  private  Map<?,?> header;
  private  String id;//实例的唯一标识,如果是静态的,可以不用加毫秒时间
  private  String className;
  private  String methodName;//用于Class的getMethod
  private  Class<?>  parameterTypes;//用于Class的getMethod
  private  Object[]   parameter;//用于Method的invoke
  RPCResponse类的member及其类型:
  private  Map<?,?> header;
  private  String id;//实例的唯一标识,如果是静态的,可以不用加毫秒时间
  private  String className;
  private  String methodName;//用于Class的getMethod
  private  Class<?>  parameterTypes;//用于Class的getMethod
  private  Object[]   parameter;//用于Method的invoke
  private  Object    result;//Method的invoke返回的参数(你要保证它可以被序列化)
  上面我之所以一直强调要保持socket传递的对象必须可以序列化是因为我用的ObjectInputStream和ObjectOutputStream来传递对象的,当然,你可以有自己的序列化规则。好了,今天就到这里了,如果你还有什么疑问,可以email给我:zzcwfp@gmail.com。或者在我的博客留言!
  补充:我只是在模拟器上实现了上述操作,真机没有试验过。注意adb forward命令使用啊,这里就不详细说了,你可以google一下。
  请关注正正博客:http://www.2009fly.com 。在主站(http://www.2009fly.com )的博客会更新快于其它站(http://www.cnblogs.com/zzc1986 , http://blog.csdn.net/zzc1986 )的博客

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348354-1-1.html 上篇帖子: Windows平台下GeoServer1、uDig的安装和使用 下篇帖子: 自学JAVA要的项目中常用jar包 从网上下下来的一个包含大部分自学JAVA要的项目中常用jar包,亲们,应该有你要的吧!!(*^__^*) 嘻嘻……
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表