android跨平台开发_手机游戏跨平台开发

android跨平台开发_手机游戏跨平台开发安卓跨平台开发实践

大家好,又见面了,我是你们的朋友全栈君。

移动端目前市面上主流的平台主要有Android和IOS两大平台,为了尽可能复用代码和节省开发成本,各大巨头都开发了自己的跨平台框架,比如Facebook的React-Native,阿里的Weex,Cordova,以及今年Google开发者大会上介绍的Flutter框架。这些框架各有优缺点,但是到目前为止都没有大规模的推广开来,在我看来主要有一下几个原因:

1、开发者生态圈还不够成熟,RN是三大跨平台框架关注人最多,生态最活跃的框架, 但是到目前为止也没有到1.0版本(最新的release是0.57.8),更别说后来者的Weex和Flutter了。生态不成熟,意味着开发文档少,可以使用的开源控件少,比如在RN上想做一个最基本的下拉刷新和上拉加载更多的listview都比较费劲。Weex已经贡献给Apache,已经很久没有更新release了。Flutter现在还在beta版本,其发展还有待观察。

2、性能问题,虽然这几大框架都对渲染性能做了优化,但是相比原生还是差一些,RN和weex都自己实现来了一个浏览器内核(JSCore),因此多了一层js解析,渲染会慢一些。比如RN的listview如果数据量太大就会出现卡顿。Flutter虽然自带绘制引擎,但是跟原生比起来还是有一些距离。

3、兼容问题,虽然这三大平台的初衷都是为了跨平台(Write/Learn once, run everywhere),但是实际应用中还是需要耗费很多的精力去兼容和适配,比如RN在Android低端机器上表现就不尽如人意,连曾经RN的坚实拥护者Airbnb都宣布放弃使用RN了。

4、开发集成成本,三个框架都需要学习新的语言React,vue,dart,weex的最大优势就是入门简单,但是版本迭代慢,RN上手门槛高,开发调试难度大,集成RN和weex框架还会加入很多so文件,增加安装包的大小至少在10M左右,这还不包括第三方的library。Flutter因为刚出来,应用的还不多,其效果还有待观察。

但是移动开发的跨平台是大势所趋,可以节省开发成本,提高开发效率,迅速响应业务变化,现在主流的应用还是使用H5和原生的通信来实现跨平台的开发。Android和IOS平台都有自己内置的浏览器内核webkit框架,跨平台的本质就是用H5/JS编写的代码能够分别运行在Android和IOS的WebView中,从而实现了一套代码两个平台都能运行的目的。

在Android平台上要实现Native和JS的通信主要通过WebViewClient和WebChromeClient两个类来实现。WebViewClient的作用是帮助WebView处理各种通知,事件请求,其主要的方法有:onLoadResource,onPageStart,onPageFinished,onReceiveError,shouldOverrideUrlLoading等方法;WebChromeClient处理JS页面的事件响应,比如网页中的对话框,网页图标,网站标题,网页的加载进度等事件,对应的响应方法有onJsAlert, onJsConfirm, onJsConsole, onProgressChanged, onReceiveIcon, onReceiveTitle等。

要实现Java和JS通信就要:

1,解决Java调JS;

2,JS调Java。

Java调用JS通过loadUrl和evaluateJavaScript两个方法。

通过webview.loadUrl(“javascript:alert(‘hello world’)”),可以在android平台将js代码注入到html页面,loadUrl方法可以直接调用js中定义的函数,也可以把android本地的assets目录下的js文件以字符串的形式注入到html页面中,但是这个注入时机一定要等到html页面加载完毕才能做,即在WebViewClient.onPageFinished的回调函数中调用,这样就相当于在html页面中直接引用了js资源文件。对于客户端来说,java调用js本质上是拼接js字符串的过程,但是调用loadUrl不能直接获取js函数的返回值。要实现Java调用js函数后,可以获取js函数的返回值可以使用webview.evaluateJavaScript方法,但是该方法只有在android4.4及以上的版本才可以使用。其他用法和loadUrl一致。

JS调用Java可以分为三种:1,对象映射;2,URL拦截;3,JS方法拦截。

对象映射是通过webview.addJavascriptInterface(new JSObject(), “javaObject”),这样可以js代码中可以直接调用javaObject对象,从而实现JS调用Java的功能,但是这个方法在android4.2以下会有安全漏洞,利用反射机制调用Android API getRuntime执行shell命令进行攻击,比如遍历sdcard,发送短信,安装木马APK等。

URL拦截是指在html页面通过iframe.src,window.open,documention.location或者href,这四种方法都可以在html页面中打开一个连接,从而会触发Java中的WebViewClient.shouldOverrideUrlLoading方法。例如在js中执行

在shouldOverrrideUrlLoading中可以根据约定的协议格式(Scheme)和协议名(Authority)获取从JS中传输过来的数据(Data)。

在JS中调用alert,console,prompt,confirm等方法就会触发WebChromeClient的onJsAlert,onConsoleMessage,onJsPrompt,onJsConfirm方法的回调。比如在js中可以调用

在onJsPrompt的message中可以获取prompt的内容,然后根据约定的协议格式可以获取数据。

为了解决JS和Native的通信问题,需要使用一个JSBridge框架(https://github.com/lzyzsd/JsBridge)用来负责H5和Java之间的通信,需要解决的问题:

1、JS互相Java调用后如何回调,将responseData传递回去;

2,JS调用Java有三种方法,如果选择哪一种方法比较合适。

针对问题1,可以在java端和js端定义一个数据结构: Message={callbackId:xxx, handleName:xxx,responseData:xxx,responseId:xxx}。将回调函数保存在callbackId中,当JS或者Java处理完数据回调的时候再讲保存在callbackId的回调函数存放在responseId,相应的回调的数据存放在responseData中,这样就能响应JS或者Java调用后的回调消息。

Js调用Java的方法虽然有三种,但是addJavaScriptInterface存在安全性问题一般不建议使用,JS中的alert,console方法都会在Html页面比较常用,confirm和prompt虽然不常用但是某些手机系统版本上会有对话框弹出,不通用,所以比较好的选择是url拦截,可以通过iframe.src触发shouldOverrideUrlLoading。

JsBridge框架的使用主要分为:

1,在H5页面加载完毕注入一个本地的js文件;

2,Java代码中注册BridgeHandler,用来处理JS发送过来的消息;

3,在本地注入的js文件中定义_handleMessageFromNative,用来接收java传递过来的消息;

4,因为客户端注入js是异步的,所以需要在js文件中注册Event监听器,成功后通知H5。

Native调用JS,例如通过

webview.loadUrl(

“javascript:WebViewJavascriptBridge._handleMessageFromNative(‘{

\”callbackId\”:\”JAVA_CB_2_559\”,\”data\”:\”just data from java\”

}’)”);

这样就可以调用JS的handleMessageFromNative方法,传递的数据格式是Message,callBackId响应js的回调,发送前会存储到HashMap中,js回调的时候根据JAVA_CB_2_559找到对应的的回调函数处理js的响应数据,具体流程如下:

Js调用Java,通过sendMessageQueue将传递的信息转换成

Message= {data: {…}, callbackId: “cb_1_1234”}

其中callbackId是js的回调函数。然后通过

iframe.src=’yy://return/_fetchQueue/[{“data”:”xxxx”,”callbackId”:”cb_1_4321″}]’,

触发shouldOverrideUrlLoading方法,java处理完js传递过来的data后,将回调函数cb_1_4321设置到

Message={responseId: cb_1_4321, responseData:XXX},

这样在js中就能处理回调函数。具体的流程图如下:

JsBridge框架提供两种Handler方法,registerHandler方法需要传入handler的名字,这样需要IOS,Android,H5三方约定这个名字,因为H5开发的的业务需求变化比较快,而且H5调用原生的方法也是随机的,所以每次都用registerHandler约定名字需要使用全局变量存放这些handler方法名不便于扩展,所以实际开发中使用defaultHanlder,H5调用原生方法的的时候约定一个cmd,即约定data={cmd:xxx,time:data:{…}},只要在原生代码中对cmd命令有对应的功能,那么H5页面就可以随时调用原生的方法。

JSBridge的改进建议,由于webview调用js方法的时候必须在主线程才能生效,所以偶然会出现java调用js失败。另外,Js调用Java偶尔也会失败,因为iframe机制不能保证每次都能触发shouldOverrideUrlLoading回调。目前JSBridge采用的是url scheme的方式,如果不考虑Android4.2以下,IOS7以下,可以采用的交互,比如直接使用addJavaScriptInterface在JS页面注入一个Native对象,将之前触发u步骤变为使用这个Native对象向Native发送消息。这种方法只是一个可行的方案,实际使用过程中目前的JSBridge方案基本上满足业务需求了。

作者:周智         宜信技术学院官网:http://college.creditease.cn/#/index

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107057.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • python 字符串替换_python字符串替换的2种方法

    python 字符串替换_python字符串替换的2种方法一、python字符串替换可以用两种方法实现:1.用字符串本身的方法2.用正则来替换字符串下面用个例子来实验:a=’helloword’我把a字符串里的word替换为python1.用字符串本身的replace方法a.replace(‘word’,’python’)输出结果是hellopython2.用正则表达式来完成替换:importrestrinfo=re.compi…

  • 手把手教你设置 IntelliJ IDEA 的彩色代码主题「建议收藏」

    手把手教你设置 IntelliJ IDEA 的彩色代码主题「建议收藏」温馨提示:本教程的GitHub地址为「intellij-idea-tutorial」,欢迎感兴趣的童鞋Star、Fork,纠错。首先,给出一系列IntelliJIDEA代码的彩色主题,供大家选择:VibrantUnknown(Darcula)FadeCommentsNicePythonSolarizedHavenjark

  • EXCEL 出错 8000401a

    EXCEL 出错 8000401a检索COM类工厂中CLSID为{00024500-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误:8000401a先用骨哥狗了一会,没解决方案,又用摆渡,也没找到方法,最后还是看微软的帮助解决了问题:1.打开DCOM配置,取消交互式用户,使用启动用户2.安全中附足够权限,不知道用户是谁就写Everyonehttp://suppo…

  • 开发MT4指标和EA(自动交易系统)

    开发MT4指标和EA(自动交易系统)对外开发MT4指标和EA(自动交易系统)开发MT4指标或EA(自动交易系统)需按照标准格式,撰写如下内容文档。而后会评估价格和你联系.联系电子邮件,alantop@qq.com指标或EA的参数是否…

  • 【Lamp】lamp配置[通俗易懂]

    【Lamp】lamp配置[通俗易懂]参考了挺多文章http://www.cnblogs.com/candle806/archive/2011/03/14/1983992.htmlhttp://blog.csdn.net/callmeback/article/details/8130190  主要是这一篇文章http://www.linuxidc.com/Linux/2012-05/61079.htmhttp

  • Angular面试题_vue框架面试题

    Angular面试题_vue框架面试题一、ng-show/ng-hide与ng-if的区别?第一点区别是,ng-if在后面表达式为true的时候才创建这个dom节点,ng-show是初始时就创建了,用display:block和display:none来控制显示和不显示。第二点区别是,ng-if会(隐式地)产生新作用域,ng-switch、ng-include等会…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号