Hybrid App(原生+H5)开发

介绍

市面上主流的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提供容器。

优点:

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

缺点:

  1. 功能/界面无法自定:所有内容都是固定的,不能换界面或者增加功能
  2. 加载缓慢/网络要求高:混合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 -g
  • cdn方式引入
  • 直接下载源码,放到指定的js文件中进行引入(后文会贴上dsBridge的源码)

H5与原生交互的核心

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

H5调用原生

steps:

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

原生端调用H5端

steps:

  1. 前端注册注册JavaScript方法以供原生端使用
  2. 客户端获取DWebView实例(DWebView:其实dsBridge对webview只做了一层封装,提供了dsBridge特有的JavaScript到Java的能力)
  3. 客户端通过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 dsbridge@3.1.4

引入:在文件夹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=' + devIddsBridge.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.定制一份约束双端的协议以用来对应方法的一一对应性(什么方法做什么事,参数、方法名、同步异步)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/180301.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UE5加载websocket模块为空

今天测试UE 发现工程启动不了,后来看到原来是websocket模块无法加载。 解决的它的方法很简单,这种问题一般会出现在源码版本的引擎或者是停电了,导致UElaunch版本损坏,解决方法是来到源码版本的引擎 这个目录下: D:\…

相机存储卡被格式化了怎么恢复?数据恢复办法分享!

随着时代的发展,相机被越来越多的用户所使用,这也意味着更多的用户面临着相机数据丢失的问题,很多用户在使用相机的过程中,都出现过不小心格式化相机存储卡的情况,里面的数据也将一并消失,相机存储卡被格式…

【案例】3D地球(vue+three.js)

需要下载插件 <template><div class"demo"><div id"container" ref"content"></div></div> </template> <script> import * as THREE from three; // import mapJSON from ../map.json; import { Or…

windows10编译高版本openssl

参考文章 参考文章中的windows编译为低版本&#xff0c;在高版本的openssl编译中已经没有&#xff1a;“ms\do_ms.bat”这个脚本了&#xff0c;现记录下编译过程 1、准备工作 安装ActivePerl&#xff0c;安装后会自动写入环境变量&#xff0c;参照参考文章测试安装成功与否&a…

涉及多种位运算操作混合类题目——通过加转三进制(扩大状态,不变枚举量):CF1033F

https://www.luogu.com.cn/problem/CF1033F 我们发现直接用二进制来做很难做&#xff0c;但我们可以观察其给的表 我们发现如果表示成和的形式是容易进行一一对应的 对于询问的时候&#xff0c;我们直接枚举每位有的和是多少&#xff0c;虽然状态是三次的&#xff0c;但是对于…

STM32HAL-完全解耦面向对象思维的架构-时间轮片法使用(timeslice)

目录 概述 一、开发环境 二、STM32CubeMx配置 三、编码 四、运行结果 五、代码解释 六、总结 概述 timeslice是一个时间片轮询框架&#xff0c;完全解耦的时间片轮询框架&#xff0c;非常适合裸机单片机引用。接下来将该框架移植到stm32单片机运行&#xff0c;单片机…

如何设置OBS虚拟摄像头给钉钉视频会议使用

环境&#xff1a; OBS Studio 29.1.3 Win10 专业版 钉钉7.1.0 问题描述&#xff1a; 如何设置OBS虚拟摄像头给钉钉视频会议使用 解决方案&#xff1a; 1.打开OBS 底下来源这添加视频采集设备 选择OBS虚拟摄像头 2.源那再建一个图像&#xff0c;随便选一张图片 3.点击虚…

学习Opencv(蝴蝶书/C++)相关——1. 前言 和 第1章.概述

文章目录 1. 整体架构1.1 OpenCV3.01.2 Opencv4.xX. Opencv cheatsheet(小抄)1. 整体架构 1.1 OpenCV3.0 对于Opencv3.x版本,网上最常见的图,图自OpenCV Tutorial-Itseez 现在已经不是500+的算法了,而是2500+,详见:About

Keras人工智能神经网络 Regressor 回归 神经网络搭建

前期分享了使用tensorflow来进行神经网络的回归&#xff0c;tensorflow构建神经网络 本期我们来使用Keras来搭建一个简单的神经网络 Keras神经网络可以用来模拟回归问题 (regression)&#xff0c;例如给下面一组数据&#xff0c;用一条线来对数据进行拟合&#xff0c;并可以预…

Apache Pulsar 在腾讯云上的最佳实践

导语 由 StreamNative 主办的 Pulsar Meetup Beijing 2023 在2023年10月14日完美落幕&#xff0c;本次活动大咖云集&#xff0c;来自腾讯、滴滴、华为、智联招聘、RisingWave 和 StreamNative 的行业专家们一起&#xff0c;深入探讨 Pulsar 在生产环境中的最佳应用实践&#x…

openpnp - 74路西门子飞达控制板(主控板STM32_NUCLEO-144)实现

文章目录 openpnp - 74路西门子飞达控制板(主控板STM32_NUCLEO-144)实现概述飞达控制底板硬件电路程序的修改END openpnp - 74路西门子飞达控制板(主控板STM32_NUCLEO-144)实现 概述 现在调试自己的openpnp设备, 在收尾, 将飞达控制板弄好, 能正常控制设备飞达安装平台上装满…

python实现从字符串中识别出省市区信息

从字符串中识别出省市区的信息分别存储,是我们经常会碰到的问题。如果用分词的方法去匹配获取比较麻烦,cpca包提供了便捷的调用函数transform。只要把含省市区的信息放进去,即可返回标准的含省市区的数据框。    本文详细阐述如何安装cpca包、transform函数参数定义,以及…

佳易王羽毛球馆计时计费管理系统软件下载,支持连接灯控

软件特色&#xff1a; 1、功能实用&#xff0c;操作简单&#xff0c;不会电脑也会操作&#xff0c;软件免安装&#xff0c;已内置数据库。佳易王羽毛球馆计时计费系统软件免安装版V17.6&#xff0c;是集计时计费、商品销售、会员管理、备注记事本、定时提醒功能于一体的管理软…

《面向对象软件工程》笔记——1-2章

“学习不仅是一种必要&#xff0c;而且是一种愉快的活动。” - 尼尔阿姆斯特朗 文章目录 第一章 面向对象软件工程的范畴历史方面经济方面维护方面现代软件维护观点交付后维护的重要性 需求、分析和设计方面团队开发方面没有计划&#xff0c;测试&#xff0c;文档阶段的原因面向…

Android应用集成RabbitMQ消息处理指南

Android应用集成RabbitMQ消息处理指南 RabbitMQ1、前言2、RabbitMQ简介2.1、什么是RabbitMQ2.2、RabbitMQ的特点2.3、RabbitMQ的工作原理2.4、RabbitMQ中几个重要的概念 3、在Android Studio中集成RabbitMQ3.1、在Manifest中添加权限&#xff1a;3.2、在build.gradle(:app)下添…

广告引擎检索技术快速学习

目录 一、广告系统与广告引擎介绍 &#xff08;一&#xff09;广告系统与广告粗分 &#xff08;二&#xff09;广告引擎在广告系统中的重要性分析 二、广告引擎整体架构和工作过程 &#xff08;一&#xff09;一般概述 &#xff08;二&#xff09;核心功能架构图 三、标…

2023年【起重机司机(限桥式起重机)】报名考试及起重机司机(限桥式起重机)模拟考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 起重机司机(限桥式起重机)报名考试参考答案及起重机司机(限桥式起重机)考试试题解析是安全生产模拟考试一点通题库老师及起重机司机(限桥式起重机)操作证已考过的学员汇总&#xff0c;相对有效帮助起重机司机(限桥式起…

基于PHP + MySQL实现的文章内容管理系统源码+数据库,采用前后端分离的模板和标签化方式

文章内容管理系统 dc-article是一个通用的文章内容管理系统&#xff0c;基于开源的caozha-admin开发&#xff0c;采用前后端分离的模板和标签化方式&#xff0c;支持文章内容管理、栏目分类管理、评论管理、友情链接管理、碎片管理、远程图片获取器等功能。可以使用本系统很轻…

Go Gin中间件

Gin是一个用Go语言编写的Web框架&#xff0c;它提供了一种简单的方式来创建HTTP路由和处理HTTP请求。中间件是Gin框架中的一个重要概念&#xff0c;它可以用来处理HTTP请求和响应&#xff0c;或者在处理请求之前和之后执行一些操作。 以下是关于Gin中间件开发的一些基本信息&am…

WorkManger学习汇总

一.使用 WorkManger主要是用来执行一定会执行的任务的&#xff0c;如即使app被杀掉、手机重启都会执行。 适用场景&#xff1a;定期重复性任务&#xff0c;如定期log上传等 使用的话首先引入库&#xff08;我使用的是2.7.1&#xff09; implementation "androidx.work:…