Java和Android环境安装与配置,将另写经验分享,读者也可百度参考其他相关资料,自行安装
打开MyEclipse2014,新建一个HTML5 Mobile Application Project,命名,例如:hello
html5程序在工程>
现在用h5开发app主要是三种模式,一种是webapp,主要是将网页版的进行打包,不能调用原生的功能。第二种是混合式app,这种能够调用一些原生的功能,体验比webapp好一些,最后一个是RNapp,现在的大部分都是这种开发模式,能够使用大部分的原生功能,跟原生app基本上没有区别了。
html5移动端web页面,和app看起来,其实没多大区别web移动端 和 app最大的区别在于:
h5web页面的本质还是网站,网站页面跳转会有白屏(页面加载/渲染中)
而app,跳转是没有白屏的,不需要加载/渲染页面,只需要加载数据资源,
听起来好像没多大区别,如果网速快,确实没什么区别
网速不足时,app的优势就体现出来了,
所以说,主要还是app的用户体验更好一些。
奇技指南
2018年11月26日发表的“360 AI音箱H5开发实践”一文中,曾简单提到“与Native交互”。本文将就此主题深入探讨H5与App交互的几种常见模式。
本文内容如下:
H5,在中国被专门用来指代开发内嵌于手机应用中的网页的技术,外国好像并没有这个说法。从技术上讲,H5是HTML5即Hyper Text Markup Language(超文本标记语言)第5版的简称。而HTML只是开发网页要用到的多种技术之一。除了HTML,还要用CSS设计界面,用JavaScript实现交互,甚至要用Nodejs实现服务端逻辑。为什么H5会被用来笼统地指代这些技术呢?我猜一是因为它简单,二是移动端网页开发技术又恰好需要这么一个概念。
移动端网页运行在手机应用内嵌的浏览器引擎中,这个没有UI的内核容器统称WebView,即iPhone的UIWebView(iOS 20–120)、WKWebView(iOS 80+,macOS 1010+)和Android的WebView。总之,WebView就是在手机应用中运行和展示网页的界面和接口(神奇的是,英文Interface,既可以翻译成“界面”也可以翻译成“接口”)。
H5与原生应用的交互都是通过原生应用中的WebView实现的。通过这个环境,H5可以调用原生应用注入其中的原生对象的方法,原生应用也可以调用H5暴露在这个环境中的JavaScript对象的方法,从而实现指令与数据的传输。
比如,在Android应用中,WebView类有一个公有方法addJavascriptInterface,签名为:
调用这个方法可以向WebView中以指定的名称name注入指定的Java对象object。这样,WebView中的JavaScript就可以通过name调用object的方法。比如:
在iOS或macOS中,需要通过创建WKWebView类的实例在应用中嵌入网页,交互过程类似。
所谓基础接口,就是首先要规定原生应用和JS分别在WebView里注入/暴露一个什么对象:
并约定在这两个对象上分别可以调用什么方法:
顾名思义,NativeBridgecallNative是由JS调用向Native传递指令或数据的方法,而JSBridgecallJS则是由Native调用向JS传递指令或数据的方法。方法签名中的参数含义如下:
基础接口只有两个对象和两个方法,JS与App间的互 *** 作则通过action和params来扩展和定义。
对于JS而言,虽然这里只定义了一个对象一个方法,但实践中,可以把action对应方法的实现附加到JSBridge上,只要把callJS实现为一个分发方法即可,比如:
这样,所有对callJS的调用,都会转化成对JSBridge上相应action方法的调用,优点是只需一行代码。
另一种实现方式是通过switchcase语句实现调用分发,比如:
这样实现的优点是所有方法一目了然,当然同样也是把所有相关接口都附加到同一个JSBridge对象上。
以上两种实现模式各有利弊。
由JS发起的单向调用App的 *** 作,主要涉及加载URL和切换到原生界面,可对应如下action:
loadUrl调用的参考协议如下:
这里NativeBridge是App的原生对象,其callNative方法被调用时,会收到一个对象(字典/映射)参数。根据这个参数的action属性的值,App可知需要执行的 *** 作是加载URL。于是再取得params属性中的url,发送请求即可。
loadContent调用的参考协议如下:
同上,这里通过params向App传递了必要参数,App负责切换到相应的原生界面。
由App发起的单向调用JS的 *** 作,主要涉及用户点击后退按钮(<),可对应如下action:
can_back调用的参考协议如下:
此调用返回的值示例如下:
顾名思义,can_back用于App询问JS:在返回上一级界面前,是否d窗提示用户?
返回值中的can如果是true,则直接返回,不提示;如果是false,则d出一个确认框,请用户确认。另一个值target是与App约定的返回目标,比如prev表示返回上一级,top表示返回顶级,等等。
双向调用是JS先调用App,然后App在完成 *** 作后再调用JS,双向通常都需要传递数据。双向调用主要涉及JS调用App原生组件和用户点击右上角按钮,可对应如下action:
loadComponent的参考协议如下:
在这个例子中,涉及JS调用App显示其实现的城市选择组件:type: 'location',用户选择完城市之后,App再调用set_location,将用户选择的城市名称传给JS:
JS根据拿到的值更新界面,完成一次双向调用。另一个例子是JS调用原生的日期选择组件,与此类似。
为什么叫displayNextButton?因为根据具体业务场景,可能存在如下三种情况:
displayNextButton协议的参考实现如下:
以上代码示例表明,JS调用App,告诉App显示“下一步”按钮,但是要禁用变灰,因为enable: false。如果传递的是enable: true,那么用户就可以点击“下一步”按钮了。点击之后,App再调用JS的save_form。最后,如果不想显示按钮,可以传递name: ''。
下面重点说一下用户点击“下一步”按钮,App调用save_form的场景。此时也分两种情况:
如果是JS通过App保存数据——可能因为App端实现了数据写入必需的加密机制——那么,JS可以在App调用save_form时将约定好的数据返回给App,由App去保存数据。
如果是JS直接保存数据,比如通过Ajax,那么在保存完数据之后,则还需要调用前面所说的App暴露的loadUrl或loadComponent方法,以告知App切换界面。当然这种情况下会出现第三次调用,但仍然属于双向调用。
本文介绍了JS与App交互的几种模式,而且只讨论了JS端的实现。在开发实践中,团队各端总会面临哪一端主导的问题。本文展示的参考实现就是H5端主导的一种实现形式。H5主导的特点是把主要业务逻辑都封装到WebView中,App主要协同配合,而优点是业务逻辑的变更不会蔓延到App。毕竟相对于H5,App的安装部署模式会造成多版本共存问题,需要尽可能控制新版本。假如由App端主导,将逻辑封装在App端,势必造成版本不受控,给整个项目或产品埋下隐患。
当然,事无绝对。具体情况还要具体分析。而且,哪方主导有时候也取决多方面因素。实践中还是要因人、因时、因势制宜。
1H5的性能很差,一般经常改的地方可以用H5,比如论坛,咨询之类的,而且限制也是很大,很多效果是没办法做到的。GUI框架的WebView普遍是这样的。如果一个APP全部由H5来做(不太可能,送审很可能被拒),那么会显得非常卡。
2用iOSSDK,如果实现热更新是比较麻烦的。对于论坛,咨询这种模块,动不动就改版,做起来比较头疼,用H5就很合适了。尤其在APP跨安卓和iOS的时候,这类模块如果直接用H5,那么就很容易共用。
H5网页App开发和纯原生的App的差距主要聚集在以下几个方面:
1、动画
动画有很多种,比如侧边栏菜单的滑入滑出、元素的响应动画、页面切换之间的过场等等,在H5之下的众多实现方法都没有办法达到纯原生的性能。一般这些的话有几种不同的选择:css3动画、javascript动画、原生动画。
css3动画非常的消耗性能,如果某一个元素用到css3动画可能还看不出来,但大面积或过场使用css3动画会让app低端手机体验非常差。最好的选择一般是通过框架调用底层的动画,但不管怎么样等于在原来的代码上包上了一层,性能还是不可避免的受到影响。
比如在一个新页面的载入上,如果调用底层动画要考虑的问题有两个,一个是本身资源页面的渲染问题,另一个是远程数据的获取。即便是这些动画能够很快的响应,但大量的css页面会导致渲染卡顿,滑入时可能会有白屏/机器卡顿的现象。为了解决这些性能问题又必须要用到预加载或模拟动画。即便是这样,滑入滑出的动画在低端的安卓机器上还是有很多问题,如果获取服务端数据处理的方式不合适,卡顿白屏的现象会更严重。具体看下面的数据获取方式。
2、获取服务端数据
首先要接受的是,这里的数据获取都是在资源页面上异步完成的,因为只有这样才能让这些资源页面完成预加载或者渲染。但是异步拿到的数据在填入页面中时可能会涉及DOM *** 作,众所周知,DOM *** 作非常消耗性能,如果页面小还好,页面稍大数据稍微复杂一点,频繁的DOM *** 作会导致明显的闪白。而且最重要的一点是,如果页面加载进来之后数据更新的速度太慢,也会让页面模板等待很长时间,对用户体验又不友好,总不能每次打开都像浏览器一样等待刷新是吧
这个问题如果没有得到解决,H5开发是很难承担大规模数据的页面,在它们之中频繁切换更是难上加难,那么肯定有人也会想到用MVVM的方式,其实我也写过一些基于MVVM的H5app开发,相对来说它们获取数据和更新数据的方式更敏捷更科学,但写的过程中又要注意很多H5独有的问题,这些问题在下面的页面切换里来讲。
3、页面切换
上面我们看到了几种不错的实现方式,比如预加载和模拟动画,甚至有批量的预加载,批量的截图模拟动画等等,虽然看起来很友好解决了不少问题,但事实上如果页面足够多就会引发另一个问题——页面的生存周期。
试想一下,如果引导页或者主页面缓存了5个子页面的资源,在跳转到响应的子页面时又会缓存这些子页面的下级页面资源,如此反复肯定会占据大量内存使APP的体验下降。那么怎么知道那些页面是需要的,最多缓存多少页面,什么时候结束哪些页面的生存周期呢?在我用过的很多H5APP的框架里都没有对这些问题有一个完美的解答,因此在页面较多内容较多的app开发中可能会因这些资源分配的问题降低性能。
这时候我们回过头来再看看MVVM的数据加载问题,实际上不管哪个MVVM框架,写过的人都知道管理这种新型的前端代码最重要的问题是内存的问题,你既要保证代码写的足够优雅没有任何内存泄露问题,也要考虑到在页面生存周期结束时它们的控制器/页面资源是否得到释放,这对全局有没有什么影响,在多个请求时也要合理的分配资源,甚至是复用这些父级页面传过来的缓存资源等等。较小的APP可能并不会有这些问题,如果你想用纯H5来开发大型app,这很可能会浪费你很多时间——而且结果还不会让你满意。
4、Android/iOS的区别
很多人都说纯H5app开发一次编写就能编译Android/iOS两种不同的APP,大大降低了成本。实际上这个观点本身就是值得怀疑的,如果你写过这类APP就能明白我在说什么,它们既不省事,又存在很多BUG,调试时尤其繁琐。举一个很简单的例子,Android和iOS在返回上一页的处理方式上就有明显的区别,iOS的顶部bar在全屏下怎样处理,Android机器出现smartbar怎样处理页面的布局,调用底层硬件时怎样区分不同的场景等等,你需要写一个又一个机型和系统的判断,然后分别在Android和iOS下调试,最后你却发现这并没有卵用,累的要死却什么没学到,只有一堆不知道什么时候会过时的经验。
现在做H5混合APP开发的人很多,但是纯H5却很年轻,很多问题都没有很好的解决,这几个是我在做这些APP时考虑最多的问题。最后说一个很少人注意到的H5优势,大家大谈H5APP时都是快速开发、低成本、多平台等等,但我却觉得它和很多APP开发方式相比有一个不同之处——图文混合的排版。正是这些复杂多变的CSS样式消耗了性能,但是它带来了排版的多样性,能够细致到每一个字宽行高和风格的像素级处理,才是H5的优异之处。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)