App开发模式

953 阅读5分钟

APP开发模式有以下四大类型:

  • Weex

  • Native App

即传统的原生APP开发模式,Android基于Java语言,底层调用Google的 API;iOS基于OC或者Swift语言,底层调用App官方提供的API。体验最后。

  • Web App

即移动端的网站,将页面部署在服务器上,然后用户使用各大浏览器访问。一般泛指 SPA(Single Page Application)模式开发出的网站。体验最差。

  • Hybrid App

即混合开发,由Native通过JSBridge等方法提供统一的API,然后用Html5+JS来写实际的逻辑,调用API,这种模式下,由于Android,iOS的API一般有一致性,而且最终的页面也是在webview中显示,所有有跨平台效果

这种模式可以用原生来实现要求高的界面,对于一些比较通用型,展示型的页面完全可以用web来实现,达到跨平台效果,提升效率

原理:Hybird实现的基本原理是通过原生的WebView容器加载H5网页进行渲染,通过JavaScript Bridge调用一部分系统能力,同步更新服务器上的H5网页也实现了动态更新,俗称混合应用。

  • React Native App

使用JS+部分原生语法来实现功能。初次学习成本较高,但是在入门后,经过良好的封装也能够实现大部分的跨平台。而且体验很好。

原生和H5的一种通讯方式:JSBridge

定义:JSBridge就是定义Native和JS的通信,Native只通过一个固定的桥对象调用JS,JS也只通过固定的桥对象调用Native。

基本原理:H5->通过某种方式触发一个url->Native捕获到url,进行分析->原生做处理->Native调用H5的JSBridge对象传递回调。

JavaScript 调用 Native:

JavaScript 调用 Native 的方式,主要有两种:注入 API 和 拦截 URL SCHEME。

  • 拦截url scheme介绍:

url scheme是一种类似于url的链接,是为了方便app直接互相调用设计的

可以用系统的OpenURI打开一个类似于url的链接(可拼入参数),然后系统会进行判断,如果是系统的url scheme,则打开系统应用,否则找看是否有app注册这种scheme,打开对应app

需要注意的是,这种scheme必须原生app注册后才会生效。

实现思路:

  • 第一步:设计出一个Native与JS交互的全局桥对象
  • 第二步:JS如何调用Native
  • 第三步:Native如何得知api被调用
  • 第四步:分析url-参数和回调的格式
  • 第五步:Native如何调用JS
  • 第六步:H5中api方法的注册以及格式

第一步:设计出一个Native与JS交互的全局桥对象

  • JS和Native之间的通信必须通过一个H5全局对象JSbridge来实现,该对象有如下特点

该对象名为"JSBridge",是H5页面中全局对象window的一个属性

var JSBridge = window.JSBridge || (window.JSBridge = {});
  • 该对象有如下方法
  1. registerHandler( String,Function )H5调用 注册本地JS方法,注册后Native可通过JSBridge调用。调用后会将方法注册到本地变量messageHandlers 中

  2. callHandler( String,JSON,Function )H5调用 调用原生开放的api,调用后实际上还是本地通过url scheme触发。调用时会将回调id存放到本地变量responseCallbacks中

  3. _handleMessageFromNative( JSON )Native调用 原生调用H5页面注册的方法,或者通知H5页面执行回调方法

第二步:JS如何调用Native

定义好了全局桥对象,可以通过它的callHandler方法来调用原生的。

callHandler函数内部实现过程:

(1)判断是否有回调函数,如果有,生成一个回调函数id,并将id和对应回调添加进入回调函数集合responseCallbacks中

(2)通过特定的参数转换方法,将传入的数据,方法名一起,拼接成一个url scheme

//url scheme的格式如
//基本有用信息就是后面的callbackId,handlerName与data
//原生捕获到这个scheme后会进行分析
var uri = CUSTOM_PROTOCOL_SCHEME://API_Name:callbackId/handlerName?data

(3)使用内部早就创建好的一个隐藏iframe来触发scheme

//创建隐藏iframe过程
var messagingIframe = document.createElement('iframe');
messagingIframe.style.display = 'none';
document.documentElement.appendChild(messagingIframe);

//触发scheme
messagingIframe.src = uri;

第三步:Native如何得知api被调用

上一步中,我们已经成功在H5页面中触发scheme,那么Native如何捕获scheme被触发呢?

Android捕获url scheme

在Android中(WebViewClient里),通过shouldoverrideurlloading可以捕获到url scheme的触发

public boolean shouldOverrideUrlLoading(WebView view, String url){
	//读取到url后自行进行分析处理
	
	//如果返回false,则WebView处理链接url,如果返回true,代表WebView根据程序来执行url
	return true;
}

Android中也可以不通过iframe.src来触发scheme,android中可以通过window.prompt(uri, "");来触发scheme,然后Native中通过重写WebViewClient的onJsPrompt来获取uri.

第四步:分析url-参数和回调的格式

Native接收到Url后,可以按照这种格式将回调参数id、api名、参数提取出来,然后按如下步骤进行:

(1)根据api名,在本地找寻对应的api方法,并且记录该方法执行完后的回调函数id

(2)根据提取出来的参数,根据定义好的参数进行转化

(3)原生本地执行对应的api功能方法

(4)功能执行完毕后,找到这次api调用对应的回调函数id,然后连同需要传递的参数信息,组装成一个JSON格式的参数

(5)通过JSBridge通知H5页面回调

第五步:Native如何调用JS

//将回调信息传给H5
JSBridge._handleMessageFromNative(messageJSON);
  • Native通知H5页面进行回调

  • Native主动调用H5方法 数据格式是:{handlerName:api名,data:数据,callbackId:回调id}

第六步:H5中api方法的注册以及格式

H5中注册供原生调用的API:

//注册一个测试函数
JSBridge.registerHandler('testH5Func',function(data,callback){
	alert('测试函数接收到数据:'+JSON.stringify(data));
	callback&&callback('测试回传数据...');
});