移动端跨平台探索 - 总览


随着移动技术的发展,跨平台技术日趋火热。颇有一股推到原生开发的气势,本系列介绍之前公司内部跨平台技术开发,以及用到的相关技术点和实现细节


1.jdhai项目介绍

在7fresh项目的开发和维护过程中,由于需要经常性的进行各种活动的支持,介于HTML的糟糕体验,我们在内部探索实现了一套轻量级的跨平台的技术实现,并在7fresh项目中进行了大量的实践,同一套代码运行在Android和ios两端,并实现了动态加载和更新!

1.1 优势

jdhai 使用 javascript作为开发语言,基于mvc思想,实现了ui,样式和代码逻辑的分离。底层由Android和ios原生控件实现,布局基于 flexbox思想。
一次开发,就可以运行在iOS、Android 平台上,具备iOS和Android原生的性能和用户体验上的优势,并且可以无需客户端更新版本做到动态更新页面功能。

2.jdhai 技术架构

jdhai 使用 xml 作为 布局文件的描述语言,使用json进行样式文件描述,使用javascript作为开发语言。iOS和Android 两端 各自实现 上述文件的解析并通过javascript建立和native代码的通信。javascript使用同一的api接口,调用各端原生代码的native实现,从而达到使用javascript开发的统一。


# 3. jdhai 使用到的技术总览
## 3.1 利用 javascript 进行前端页面开发 使用javascript同原生代码进行交互,为此我们借助 javascript 引擎解决通信问题。通过调研 duktape,javascCore 等引擎,我们最终选用了 duktape-Java 这个基于duktape 的引擎实现。

duktape 部分可以参考: Android上使用的javascript引擎 - duktapeJava篇

3.2 利用yoga和flexbox布局思想进行样式文件编写

flexBox布局是 W3C 在2009年 提出了一种新的布局方案,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持!

3.2.1 yoga - Facebook 跨平台布局项目

FaceBook/Yoga 是一个基于Flexbox思想的布局项目,他提供了 java,android,ios 等多个平台的实现。这使得我们可以借助yoga 利用同一套样式文件运行到不同平台上。也为我们跨平台项目的布局提供了一种解决方案!

3.2.2 yoga的Android实现 yogaLayout

yogalayout 是 yoga 项目中的Android 实现,他封装了一个 使得可以方便的以flexbox的规范来进行放置子控件的ViewGroup,而不用关心如何把flexBox转化成ViewGroup布局。

3.2.3 yogaLayout使用

1
2
3
4
5
6
7
8
9

View child = new View(context);
YogaNode yogaNode = new YogaNode();
yogaNode.setHeight(10);
yogaNode.setWidth(10);

YogaLayout layout = new YogaLayout(context);
layout.addView(child,yogaNode);

yogalayout addview接收2个参数,一个是我们要添加的view,另外一个 yoganode 就是约束子view是如何进行布局的。假如我们有如下的 json文件

1
2
3
4
5
6
7
"flexDirection": "row",
"justifyContent": "flexStart",
"alignItems": "center",
"width": "100%",
"height": "57",
"backgroundColor": "FFFFFF"

那么我们可以将上述json描述转化为 yogaNode属性

1
2
3
4
yogaNode.setFlexDirection(YogaFlexDirection.ROW);
yogaNode.setJustifyContent(YogaJustify.FLEX_START);
yogaNode.setAlignItems(YogaAlign.CENTER);

如此我们使得我们动态下发样式成为一种可能,这样也就可以动态改变页面布局的展现外观了。


FlexBox部分的学习可以参考 阮一峰的FlexBox教程

3.3 基于xml的布局文件描述

1
2
3
4
5
6
7
8
9
10
<view classX="floor-10">
<view classX="11-left">
<listFlexImage ID="11-image1" classX="coupon_image_11"/>
<image ID="11-markImage1" classX="10-markImage"/>
</view>
<view classX="11-middle">
<listFlexImage ID="11-image2" classX="coupon_image_11"/>
<image ID="11-markImage2" classX="10-markImage"/>
</view>