Hybrid App(原生+H5)开发

您所在的位置:网站首页 原生开发和h5开发哪个好一点 Hybrid App(原生+H5)开发

Hybrid App(原生+H5)开发

2024-07-05 04:08| 来源: 网络整理| 查看: 265

介绍

市面上主流的hybrid app框架主要有

React Native:由FaceBook开发,使用JavaScript和React来构建原生应用程序Flutter:由Google开发,使用Dart语言。Flutter使用自己的渲染引擎Ionic:基于 Web 技术(HTML、CSS 和 JavaScript),使用 Angular 框架。Ionic 提供了一组 UI 组件和工具,使开发人员能够构建跨平台移动应用程序。

还有hybrid app框架,但是我本人没有进行过多的涉及,这里就不展开了,想要进一步了解的友友们可以自行查阅资料哈。我在这主要是想讲讲使用hybrid app开发时的一些使用方案,并且结合自己现在做的,总结一下自己的心得。

要解决的问题

web调用原生(实质是JavaScript调用Java)原生调用web(实质是Java调用Java)数据通道的搭建---性能及易用性 原生+webVview方案

这是最常用的Hybrid方案之一。应用的主要框架由原生代码构建,同时在应用的某些部分内嵌入WebView组件,用于显示Web页面加载Web应用。Web页面通过WebView运行,并可以与原生代码进行通信。通俗点来说,就是网页的模式,通常由“HTML5云网站+APP应用客户端”两部分构成。混合开发是一种取长补短的开发模式,原生代码部分利用WebView插件或者其他框架为H5提供容器。

优点:

开发效率高,节约时间。同一套代码在Android和IOS上基本都可以使用更新迭代以及部署比较方便,每次升级版本只需要在服务器端升级即可,不需要再上次App Store进行审核代码维护方便,版本更新快,节约产品成本基于web,但是同时也可用拥有原生支持的业务可离线运行

缺点:

功能/界面无法自定:所有内容都是固定的,不能换界面或者增加功能加载缓慢/网络要求高:混合APP数据需要全部从服务器获取,每个页面都需要重新加载,因此打开速度慢,网络占用高,缓冲时间长,容易让用户反感

但是webview也是有一定的缺点的,即web应用的体验无法达到原生应用的体验。但是开发效率高,被很多app所用。比如京东、淘宝、今日头条等APP都是利用混合开发模式而成的。这也是目前笔者开发团队中开发APP时最经常使用到的方案。

H5和原生如何交互的呢?

        H5与原生APP的交互指的是在原生APP中嵌入H5页面,是的用户可以在原生APP中直接访问H5页面并进行交互操作。H5与原生APP交互原理是通过webview实现的。那么webview又是什么呢?

webview

webview是Android和IOS系统中提供的一个组件,使得可以在原生APP中嵌入H5页面。webview可以加载HTML、CSS、JavaScript等web技术,同时也可以调用原生APP提供的API,实现与原生APP的交互

H5与原生交互方式

        在H5页面中,可以通过JavaScript调用原生提供的API,实现与原生的交互。原生APP需要提供一个JavaScriptBridge类,用来接收H5页面发来的请求,并执行相应的操作。

        我这里主要想讲一下如何应用第三方框架实现H5与原生之间的交互。目前比较流行的支持H5与原生App之间交互的框架有:WebViewJavaScriptBridge、JSBridge、HybridBridge等。这些框架都提供了API接口,方便H5页面与原生APP的交互,同时也提供了一些辅助功能,如:H5页面的路由跳转、原生APP的Toase提示、H5页面的Loading动画等。

        笔者主要是从事前端开发的,那么也就是在进行Hybrid APP开发时负责的是H5页面的开发,然后我们团队用到的实现与原生APP之间交互的第三方框架主要是dsBridge,所以接下来我也主要围绕dsBridge展开,讲述H5与原生交互的一些主流程以及实际应用。

DSBridge 介绍 国内推出的JavaScript bridge跨平台混合开发框架官方提供了Android/ios版本,真正实现跨平台DSBridge支持同步及异步调用(DSbridge是唯一一个支持同步调用的javascript bridge)无需iFrame,性能好Github地址: IOS:GitHub - wendux/DSBridge-IOS: :earth_asia: A modern cross-platform JavaScript bridge, through which you can invoke each other's functions synchronously or asynchronously between JavaScript and native.Android:GitHub - wendux/DSBridge-Android: :earth_americas: A modern cross-platform JavaScript bridge, through which you can invoke each other's functions synchronously or asynchronously between JavaScript and native. DSBridge的接入方式 原生端 直接源码接入 下载DSBridge源码,作为独立的Module接入工程Gradle依赖 配置Gradle脚本,Sync自动接入 H5端 npm进行下载:npm install dsbridge -gcdn方式引入直接下载源码,放到指定的js文件中进行引入(后文会贴上dsBridge的源码) H5与原生交互的核心

在web和原生之间进行交互,如传递数据,调用函数,那么其交互的核心就是要解决双方之间的通信问题,且其中分为H5调用原生提供好的接口,和原生调用H5注册好的方法。那么H5和原生之间是如何通信的呢?

H5调用原生

steps:

原生在webview上注册方法,以提供JavaScript调用H5初始化DSBridge上下文环境(H5便可以使用DSBridge提供的一些api方法)H5端使用dsBridge.call()直接调用原生端提供的方法 原生端调用H5端

steps:

前端注册注册JavaScript方法以供原生端使用客户端获取DWebView实例(DWebView:其实dsBridge对webview只做了一层封装,提供了dsBridge特有的JavaScript到Java的能力)客户端通过callHandler函数调用H5注册的JavaScript方法,并且传入一个回调函数。   同步调用及异步调用

原生端注册同步异步方法的方式

同步调用:public object handler(object arg) 参数arg是给H5回传的数据异步调用:public void handler(Object arg,CompletionHandler handler) 参数arg是给H5回传的数据handler是回调接口,在前端执行一定操作逻辑之后,通过handler去回调消息 原生提供给H5调用的方法 同步调用

1.原生端注册同步方法

注意点:

原生端注册同步方法,参数msg必填,h5可以不传注解必须加上,h5端才能调用(dsbridge的一个安全措施)

 2.在指定url的webview页面注入刚才写好的提供给H5调用的方法,这个才能实现真正供H5调用

3.H5端进行调用

初始化DSbridge(引入DSBridge)使用dsBridge.call('方法名',obj)    // obj是在指定方法中传给原生的参数 

效果(这里实例的是安卓应用):

 

异步调用

 步骤跟同步调用大同小异,这里就不展开。但是需要注意的是,这里呀原生异步注册时和H5调用时区别

H5注册方法供原生调用 同步调用

1.前端注册同步方法

2.原生端调用H5注册的同步方法

逻辑梳理:

1.这里loadUrl指明了webview指定页面,点击指定元素触发onClick方法

2.方法中调用了callHandler方法调用了H5注册的toUpper方法,同时传入'hello'参数。

3.H5拿到参数之后,对其进行操作,这里是大小写转换,

4.H5将转换后的数据return给到原生端,原生端拿到retValue值进行一些其他操作(这里进行Toast)

异步调用

1.前端注册异步方法

2.原生端调用H5注册的异步方法

逻辑梳理:

1.前些步骤与同步调用一样

2.差异在于前端注册异步方法是没有传递其他参数,直接传一个回调函数,前端自行决定执行一些其他操作逻辑

总结:以上便是通过原生端和H5几个简单的例子说明H5是如何通过DSBridge实现与原生端的交互的。接下来我将从H5端实际项目出发,讲讲我在进行hybrid app开发时,是如何使用DSBridge实现与原生端的通信的。

项目中的应用 引入DSBridge

我在项目中使用的是直接下载源码,放在js文件中,然后再项目入口文件中进行初始化(便可以全局引用),当然也可以使用下载依赖的方式,然后再main.js文件中使用node模块进行require导入。

方式1:

安装

npm install [email protected]

引入:在文件夹src\utils\dsbridge.js中引入(这里可以做一层封装)

var dsBridge = require('dsbridge') export default { callmethod (name, data, callback) { callback(dsBridge.call(name, data, callback)) }, registermethod (tag, callback) { dsBridge.register(tag, callback) } } 方式2

安装

下载deBridge.js源码放在src\utils\dsbridge.js文件下

引人:在main.js文件中引入

import dsBridge form '../src/utils/dsbridge' 使用 定制协议

1.【通用】跳转新页面 / gotoPag

方法名:gotoPage

是否同步:同步

功能:原生端提供给 H5,用于页面跳转

参数:{ url: '' }

返回值:无

H5 示例:

let url = "http://192.168.150.148:8000/device/timer" + "?deviceId=" + devId; dsBridge.call("gotoPage", { url: url })

 2.获取账户信息 / getAccountInfo

方法名:getAccountInfo

是否同步:同步

功能:获取家庭名称、设备名称信息

参数:无

返回值:homeName 【家庭名称】, homeTimezone【时区】

H5 示例:

let homeRes = dsBridge.call("getAccountInfo", {}); // 返回 { homeName: "test", homeTimezone: 0 }

3.局域网下图片相对路径处理 / imgSrcBase64

方法名:imgSrcBase64

功能:H5 传回图片相对路径,原生对缓存图片进行 base64 处理

是否同步:异步

传参: { src:'' }

4.返回:base64 字符串 / imgSrcBase64CallBack

方法名:imgSrcBase64CallBack

是否同步:异步

功能:原生返回缓存图片的 base64 字符串

返回:base64 内容

注:原生端将缓存图片转 png 格式,再进行 base64 处理,返回 base64 字符串,H5 自 行拼接前缀:data:image/png;base64, 

调用原生注册的方法

一般在项目中需要调用到原生端注册的方法的业务方法,我会抽离到一个文件中集中管理。比如我将其放在utils/dsBridgeSend.js文件中

export default { /** * 定时界面跳转 * */ toTimePage(devId) { // 测试用 let url = 'http://192.168.151.30:8001/device/timer' + '?deviceId=' + devId dsBridge.call('gotoPage', { url: url }) } /** * 获取设备使能值信息 * */ getDevEnable() { dsBridge.call('getDevEnable', {}) }, /** * 导航栏配置公共方法 * */ pageBarSetting(devName) { let config = { hiddenBar: 0, title: devName, left: [ { type: 2, localImageIndex: 7 } ] right: [ { type: 2, localImageIndex: 9 } ] dsBridge.call('configTopBarWithParams', config) }, /** * 调用后台接口通用方法-通过原生端 * */ requestFunction(ind, params) { let requestItem = requestItem.method, url: requestItem.url, callBackMethodName: requestItem.callBackMethodName, errorCallBackName: requestItem.errorCallBackName, params: params } dsBridge.call('requestFunction', query) }, } 注册方法以供原生调用

H5这边注册方法以供原生调用,  mounted() { 这个时机一般是发生在页面(或者说webview页面)加载时,所以一般是放在页面挂载的声明周期中【Vue2:mounted(),Vue3:onMounted()】

mounted(){ let _this = this; dsBridge.registerAsyn("async", { tag: "async", queryDeviceInfoCallBack: function (response) { if (_this.$dsBridgeSend.handleError(response)){ const res = JSON.parse(response).result; // 解析状态值 _this.setStatus(res.status); } }, ctrlSucCallBack: function (response) { const res = JSON.parse(response) // 接收相同的deviceId才进行处理返回值 if (_this.$common.matchDeviceId(response, _this.commonObj.deviceId)) { // 发送指令后 - 获取返回值 _this.changeIdList.map((i) => { i.changeId++; _this.updateStatus(res.deviceStates) } }, left_0_click: function (responseCallback) { dsBridge.call("goBack", 4, function () {} responseCallback(); }, right_0_click: function (responseCallback) { if (Number(_this.isEdit) === 1) { _this.deleteContact() } else { _this.addContact() } responseCallback(); }, }); }, 总结:

混合开发的一个主要流程:

1.根据需求规划,哪些业务是H5负责,哪些是原生端负责

2.定制一份约束双端的协议以用来对应方法的一一对应性(什么方法做什么事,参数、方法名、同步异步)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3