移动端跨平台框架 MVP

What I cannot create, I do not understand.
只要我不能创造的,我就还没有理解。
—— Richard Phillips Feynman

目标 —— 渲染 HelloMax 页面

渲染效果

跨端方案

Any application that can be written in JavaScript, will eventually be written in JavaScript.
任何能被 JavaScript 编写的应用,最终都会用 JavaScript 实现。
—— 阿特伍德定律

目前业内主流的有 Flutter、ReactNative、Weex、小程序。

思路

使用 JS 编写页面,最终映射到 Android 元素页面,并且做到组件类型、样式、布局以及事件的一一映射。

QuickJS

背景

作者:Fabrice Bellard

高中时开发了可执行压缩程序 LZEXE

1996年,编写了最快最小的 C 语言编译器 TinyCC

1997年,提出了最快速的计算圆周率的算法,比传统的 BBQ 算法要快 47%

1998年,编写了一个简洁的 OpenGL 实现 TinyGL

2000年,化名 Gérard Lantau,创建了 FFmpeg 项目

2003年,开发了 Emacs 的克隆版本 QEmacs

2004年,编写了一个只有 138KB 的启动加载程序 TCCBOOT,可以在 15 秒内从源代码编译并启动 Linux 系统

2011年,使用 JavaScript 写了一个 PC 虚拟机 Jslinux

2014年,提出 BPG 格式,用来替代 JPEG

2019 年,QuickJS 发布,支持最新 ES2020 标准,非常适合用在嵌入式开发中,编译产物只有几百 KB。

源码下载与编译

最新版本(2021-03-27),make 指令编译成平台相关的可执行文件 - qjs

运行 JS 文件:

API 梳理

与 Android 工程集成

Any problem in computer science can be solved by another layer of indirection.
计算机科学中的所有问题都可以通过中间层来解决。
—— 大卫·惠勒

FFI(Foreign Function Interface) - JNI

NDK 提供了如下工具集与功能:

  1. 包含将 C/C++ 源代码编译成本地库的工具(编译器、连接器等)
  2. 提供将编译好的本地库插入到 Android 包文件(.apk)中的功能
  3. 在生成本地库时,Android 平台可支持的系统头文件与库
  4. NDK 开发相关的文档、示例、规范

Talk is cheap. Show me the code.
屁话少说,放「码」过来。
—— Linus Torvalds

动态库

创建 CMakeLists.txt,生成 libmaxtoy.so 动态库。

配置 Android 工程打包脚本。

编译生成动态库。

测试函数库调用。

使用 nm 命令查看动态库函数。

自动加载动态库。

编写单元测试。

引擎方法的封装与调用

现在开始封装 JS 引擎核心 API,我们命名为 JS Engine。它提供 JSContext 初始化,销毁以及执行 JS 等方法。

编写单元测试用例。

1.向 JS Context 中注册全局方法

创建 JS 运行环境后,在执行业务 JS 代码前,执行自定义 JS 代码,从而注入全局对象或方法。有两种注入方式:

a.C++ 侧

b.Java 侧(本方案)

2.JS 创建视图元素,Native 创建相应 View

待实现

  1. 样式布局与事件处理;
  2. 组件管理与内存释放;
  3. 原生能力的封装及调用,如 console.log。

总结

  1. 牵涉技术栈较复杂 C/C++/JS/Android;
  2. 相比于 H5 方案,页面性能流畅,瓶颈主要在于 JS 引擎层;
  3. 由于内存安全的问题,C++ 可用 Rust 替代。