◆黎茂林 王天鑫 魏嵩 闫冉 宿世博 陈晓宇
跨平台移动应用开发技术研究
◆黎茂林 王天鑫 魏嵩 闫冉 宿世博 陈晓宇指导教师
(北京信息科技大学 北京 100083)
为提高移动应用开发效率,研究了基于HTML5和WebView的跨平台移动应用开发模式,可适用于移动Web开发、微信嵌入、Android应用开发等场景;对跨平台移动应用开发核心技术要点进行了研究与总结;期望为相关研究提供相应的基础与借鉴。
跨平台;混合开发;WebView;HTML5
随着移动端的不断发展,Android(安卓系统,由谷歌公司和开放手机联盟领导及开发的移动操作系统)占据着绝大多数的市场份额,移动端的便捷性使安卓应用软件呈井喷式的增长。Web应用的便捷性也是不能忽视的,这也使得Web应用也占据着很大的市场份额。由于这两种应用程序采用了不同的开发模式,同一应用若想应用到安卓、Web上通常就需要采用两套开发技术、两组开发人员,这对开发成本、开发时间、后期维护等都会成倍地增加。为解决这个问题,本文提出了使用WebView框架,只需完成Web的开发,通过WebView框架简单的混合开发,就能完成Android应用的开发,极大减少了开发时间、开发成本、也为后期维护减少工作量。
HTML5技术在HTML4.01的基础上做了集合并革新。HTML5的便捷性使得HTML5程序通过浏览器就能运行,这样用户就可以在个人电脑、智能手机或平板电脑上任意访问程序,这给用户带来了极大的便捷性。HTML5新增的地理定位功能和数据存储功能在本APP中有所应用。
图1 浏览器高层结构
(本图来源:How Browsers Work: Behind the Scenes of Modern Web Browsers,https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/)
WebView作为Android中一个非常重要的一个控件,它基于webkit引擎来展示我们所写的web页面,WebView控件的作用是来显示和渲染Web页面,可以直接使用html文件,还可以和JavaScript交互调用,来实现混合开发。
由于我们首先进行了Web应用的开发,然后进行安卓二次开发,在开发过程中主要有以下几个技术的关键点。
基于HTML5开发的应用,移植到APP中需要进行适应性修正,本节就过程中的H5界面显示、跳转、底部导航定位、引导页设置等平台差异性问题进行了研究与总结。
应用移植首先需要解决界面显示问题,具体解决方案如下:
①首先准备工作,我们需要在安卓项目中main文件下新建一个assets文件夹,把所需的h5、css、JavaScript等文件全部导入进来。
②WebView中loadUrl方法可以完成对网页的加载,这时我们只需要把要加载的h5文件找到就可以了。首先loadUrl参数中我们要清楚协议格式,由于我们的h5是本地文件,所以要使用File协议(若是网络文件则要http协议);然后找到我们新建的assets文件,因为我们所有的h5文件都保存在这个文件下,最后找到需要加载的h5页面;需要注意的是,由于安卓的内核是Linux,在路径的表达方式上采用的是Linux的方式,还需要注意的是,我们不能直接通过assets来访问我的h5文件,需要把assets转换为android_asset,这样才能有效访问到我需要加载的h5文件。
跳转问题,具体解决方案如下:
除了只能显示界面是不够的,我们还需要界面可以实现跳转。Android提供了两种显示网页的方法如下图,若没有设置其对应的WebViewClient方法,则会由系统(Activity Manager)来处理该url,系统通常是打开外部浏览器或者弹出浏览器选择对话框。这里我们并不希望在外部的浏览器中打开,这时我们需要自己来处理这个url;将在setWebViewClient方法中的shouldOverrideUrlLoading函数在加载网页需要重新定向的时候回调,我们重写此函数,告诉程序需要接管对网页的加载的控制,该方法返回true值时,系统就不会调用外部浏览器来处理该url。此时我们只需要在此函数中每次都判断当前页面是否含有url值,若有的话我们就调用loadUrl,这就实现了页面的跳转。
图2 Android提供了两种不同的方式显示Web页面
(本图来源:安卓开发者文档 https://developer.android.google.cn)
关于底部导航定位功能,解决方案如下:
①原来实现这个功能往往是通过js获取页面的高度来实现的,这里我们采用的是纯CSS的方法来实现的,通过固定底部的高度,通过绝对定位的方法来实现。
②首先我们需要设置body的高度充满整个屏幕(min-height:100vh),然后让body作为底部绝对定位的参考点,最后设置底部为绝对定位,并设置一个固定值,设置宽度让其占满整个屏幕。
图3 底部导航栏的实现
引导页的实现方案如下:
①首先我们需要新建一个活动,让它继承Activity类,并在其对应的布局文件中添加一个ImageView组件,用来显示我们事先放在资源文件里引导页图片。
②第二步我们要修改活动的启动顺序,原来我们启动后首先打开的是主活动,现在我们启动后需要先打开引导页。在安卓AndroidManifest.xml文件中android.intent.action.MAIN决定了首先显示哪一个活动,android.intent.category.LAUNCHER表示该活动允许用安卓系统的启动器来启动它,我们把这两个从原来的主活动中转移到引导页的活动中去,这样的话,我们在启动时,首先就到了引导页了。
③如何从引导页跳转到主活动?在引导页活动中首先我们需要用intent机制来实现引导页活动和主活动之间的跳转,(Intent(引导页类名.this,主活动类名.class)),在安卓handler.sendEmptyMessageDelayed方法可以指定多少毫秒后发送消息,我们把活动之间的跳转封装成函数,再调用以上方法,设置响应时间,这就完成了多少毫秒后引导页向主活动的跳转。
图4 引导页的实现
基于HTML5的开发,并移植到Android中过程中,我们对如何实现Web定位功能、在APP中如何实现定位进行了研究与总结
关于Web定位功能的解决方案如下:
①Web开发时使用了HTML5新增的地理定位功能,在用户同意获取位置的前提下,通过HTML5 Geolocation API来获取用户的地理位置,再使用getCurrentPosition()方法可以较为准确地获取到我们的位置信息,最后通过showPosition()函数显示出经度和纬度信息。
②只是获取到经纬度,这样给人感觉不够直观,我们还需要结合地图,在地图上显示出我们的位置。这里我们使用的是高德地图,在高德地图开发者官网上申请一个密钥,在页面中引入高德API;添加一个div标签作为地图容器,并为该div指定id属性。
③通过AMap.Map(‘div的id’)方法创建地图,有了地图后,我们通过AMap.plugin方法引入高德的AMap.Geolocation定位插件,在定位插件中我们通过设置enableHighAccuracy方法来是否实现高精度定位,通过timeout设置定位响应时间等等。
图5 实现Web定位
在APP定位问题解决方案如下:
①首先我们得让该应用程序有定位权限,需要在AndroidManifest.xml中配置access_coarse_location粗略定位的权限和access_fine_location精确定位权限。
②然后在主活动里允许相关的功能的实现,因为我们先实现网页的定位,在安卓中我们就必须允许应用调用JavaScript,定位肯定离不开地理定位的功能(setGeolocationEnabled(true)),当H5调用地理位置API时,会先通过WebChromeClient.onGeolocationPermissionsShowPrompt申请授权,我们通过origin来允许使用定位的API,这样我们就实现了定位(注意:从API24开始,仅支持安全源(https)的请求,由于我们导入的是本地的html文件,这就不会存在定位请求会被拒绝的问题)。
如何在APP中使用DomStorage,我们进行了相关的研究与总结:
①DOM Storage是HTML5中新增加的一个特性,主要功能是用来作为本地存储,DOM Storage分为两种,这里我们使用的是localStorage用来长时间存储。
②首先我们得让应用支持DomStorage(setDomStorageEnabled(true)),然后我们就需要设置缓存(setAppCacheEnabled(true)),并设置它的缓存路径(setDatabasePath(path)),这里的路径(path)也需要自己来设置。
图6 在真机上测试定位
图7 使用localStorage完成本地存储
本文通过对WebView的深入了解,针对Web应用和Android应用开发需要两套不同的开发技术,极大的增加开发成本、时间和后期维护等问题,提出了使用WebView来完成跨平台的开发的解决方案,通过对相关关键技术的研究可以极快并且有效的完成Android应用的开发,极大缩减我们的开发时间。
[1]郭霖.第一行代码Android[M].第二版.北京:人民邮电出版社,2016.12
[2]任平红,陈矗.Web编程基础:HTML5、CSS3、JavaScript[M].第2版.北京:清华大学出版社,2019
[3]Andy Rubin Android developers[EB/OL].[2019-09-04].https://developer.android.google.cn/
本文由北京信息科技大学2020年大学生创新创业训练计划项目资助