写给Android开发者看的『微信小程序和Android开发的对比』

1. 前言

1.1 微信小程序

微信小程序近期可谓是动作频出,仅最近新增的能力就有:
* 允许个人开发者申请注册小程序、
* 公众号可以打开小程序、
* 可以在 App 分享、
* 支持识别图片二维码打开小程序、
* 可以支持第三方平台配置、
* 新增数据分析接口、
* 代码包大小从1M扩大到2M、
* 推出小程序码
* 公众号关联小程序新规则、
* 公众平台新增快速创建小程序、
* ……

种种迹象表明,微信对小程序的期望值是很大,所以在它推出的几个月效果没到达预期的情况下,之前的很多『克制』也就逐渐变成『放肆』了 —— 不过不管小程序以后的发展到底怎样,对我们开发者来发,多了解一些总是没有坏处的。

1.2 为什么要写这篇文章

他山之石,可以攻玉。
对于是技术人来说,多了解一些不同的技术、不同的开发模式、不同的架构思想,提高技术『广度』,对于自己的成长是十分必要的。
所以,本文就是从一个 Android 开发者的角度,从项目工程方便切入,来分析一下『微信小程序』跟『Android App』开发上的一些异同。
『微信小程序』开发是一个相对较新的技术,希望通过本文,能让你对它多一些了解。

1.3 本文的目标读者

因为内容是从Android开发的角度来谈的,所以我假设你已经对 Android 开发比较熟悉了。并且对微信小程序的开发也比较感兴趣,如果要是再能有些 javascript、css 的基础的话那就更好了!

2. 开发语言的对比

2.1 Android 的开发语言

Android 开发我们已经比较熟悉——
* 主要开发语言是 Java(当然还有 Kotlin/Scala/Groovy,暂时不在本文讨论的范围内);
* 另外使用 xml 文件来描述界面;
* 使用 AndroidManifest.xml + gradle 文件来配置项目;

2.2 小程序的开发语言

作为对比,进行微信小程序开发所用的语言是这些——
* 主要开发语言是 javascript
* 使用 wxml + wxss 文件来描述界面;
* 使用 app.json + app.wxss 文件来配置项目;

2.3 wxml、wxss 是什么?

wxml(WeiXin Markup Language) 基本约等于是 xml。微信之所以没有直接使用 xml ,可能是为了以后扩展方便一些(野心很大)。
同理,wxss(WeiXin Style Sheets) 基本约等于是 css。也是微信扩展了一些功能,比如统一的尺寸单位 rpx

2.3.1 小程序为什么要使用 wxml + wxss 来描述页面?

对于 Android 来说,对于页面的描述基本上在 xml 中定义的,比如:

<framelayout android:id="@+id/layout"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
  <textview android:id="@+id/textViewHello"
    android:textSize="20sp"
    android:textColor="#f00"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:text="Hello World!"></textview>
</framelayout>

这是一个简单的典型的示例,这个文件就是描述了两部分内容:

  1. 页面结构: 一个 id 为 layout 的 FrameLayout, 它的内部包含一个 id 为 textViewHello 的 TextView 。
  2. 页面样式: FrameLayout 和 TextView 各自的属性:width、height,TextView 还有字号、颜色、文字内容等。
    而微信小程序所使用的 wxml + wxss 方式:
    some.wxml:
<view class="userinfo">
  <image class="userinfo-avatar"></image>
  <text class="userinfo-nickname">张三</text>
</view>

some.wxss:

.userinfo {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.userinfo-nickname {
  width: 128rpx;
  color: #aaa;
}

很明显可以看出:wxml 是负责了页面结构的展示;而 wxss 则负责了对页面样式的定义。
这种把结构和样式分离的做法,其实是延续了网页开发中的习惯(html + css)。
这样做的好处起码有两个:
* 一是使代码的职责划分更加明确,结构清晰。
* 二是可以避免许多重复的代码。(你在写 Android 的 xml 文件时,有没有经常碰到有许多重复的属性,需要抽离成一个 style 出去的?这就是基本是样式表的思想了)

3. 工程结构对比

3.1 小程序的工程结构

小程序的工程结构

——看起来还是挺简单的结构:
* pages
* index
* index.js
* index.wxml
* logs
* utils 文件夹
* 三个以app命名的文件: app.js 、 app.json 、 app.wxss
我们来梳理下文件功能:

3.2 app 相关: app.js 、 app.json 、 app.wxss

这三个文件用以描述小程序 app 相关的内容,他们的命名是固定这样的,位置也固定是在根目录下。

3.2.1 app.js

app.js 基本相当于 Android 中的 Application 类,文件中主要是有一个 App()函数,来进行小程序的初始化操作。
* 它提供了一些关于整个小程序生命周期的回调函数: onLaunch、onShow、onHide、onError 等。 比如如果开发者有一些需要在小程序启动时执行的操作,就可以在 onLaunch 函数中执行。

【对比 Android】我们在 Application 的 onCreate 函数中的初始化操作。
* 它提供了一个 globalData,用以存储整个小程序使用期间的公共数据。
【对比 Android】有时候我们也会在自定义的 Application 放一些数据,供不同的页面来使用。
* 小程序提供了一个全局的 getApp() 方法用以获取小程序的 App 实例。
【对比 Android 】想一下 getApplication() 方法~ 😀

3.2.2 app.json

app.json 的作用跟 Android 中的 AndroidMainifest.xml 文件很相似 —— 都是静态化的配置文件。
* 声明、设置各个页面的路径:页面必须要先在这里声明之后才能使用。
* 配置页面的样式(导航栏颜色、文字字体等)
* 配置底部的Tab栏
* 设置通用的TimeOut时间、是否是debug模式等

【对比 Android 】Activity 也是同样需要在 AndroidMainifest.xml 文件中进行声明,另外 App 的主题也可以在这里设置。

3.2.3 app.wxss

app.wxss 定义全局的样式 —— 其定义的样式会作用于每个页面。比如在 app.wxss 中加入:

text {
  padding:5px;
}

就可以给所有的 text 控件添加 5px 的 padding 。
当然,页面本身的 xxPage.wxss 可以定义局部样式来覆盖全局样式。

【对比 Android 】Android 中暂时没有类似 app.wxss 的全局设定,我们需要在每个 layout.xml 中定义每个控件的属性,即使可以用 style 文件来抽离一些统一的样式,但还是需要在每个 View 的属性上去设置使用这个 style —— 从这方面看,使用 wxss 更有优势一些。

3.3 utils 文件夹

根目录下的 utils 文件夹中有一个 util.js 文件,这个故名思意,是类似于 Java 中的一些工具类的存在。
utils 文件夹其实是一个非必须的结构,而它之所以出现在官方的 HelloWorld 工程中,是作为一个代表,表明了开发者在这里是可以自定义新的文件夹和结构的。微信小程序作为一个使用 js 来开发的平台,是可以使用许多第三方的 js 库的,对于这些第三方库,以及其他的图片资源等,都可以放到自定义的文件夹中。

3.4 pages 文件夹

pages 文件夹下包含两个子目录:index 和 logs ,两个目录的结构都是基本一样的,都是包含四个相同主名称的文件: xx.js、xx.wxml、xx.json、xx.wxss 这几个文件。
这样的一个典型结构表明它是一个小程序的页面,四个文件的作用分别是:
* xx.js : 页面的主要逻辑 【相当于 Android 的 xx.Activity 】
* wxml :页面的结构 【相当于 Android 的 布局文件 activity_xx.xml 的结构部分】
* wxss :页面的样式 【相当于 Android 的 布局文件 activity_xx.xml 的样式部分】
* json :页面的配置,作用跟上文讲的 app.json 作用差不多,但只能配置 window 相关的属性,会覆盖 app.json 中的同名配置。
在 Android 中 ,xx.Activity 和布局文件 activity_xx.xml是在不在同一个目录下的,需要使用 setContentView 来把他们相关联。
但是在微信小程序中,这个工作不需要手动去做,微信强制要求需要一页面相关的四个文件需要命名一致,并且要放在同一个文件夹下。

4. 视图更新方式对比

在视图的动态显示上,微信小程序使用了数据绑定(data-binding)的方式。
如果你之前使用过 AngularJS 或者 Vue.js 等这些流行的 js 框架,那么你肯定对数据绑定并不陌生。它是一种把一个控件的属性绑定到某个数据对象(view-model)的属性的方法,这样在改变数据对象属性的时候,所对应的控件属性也就会相应变化 —— 在开发中,这种方式会使得对 View 层的显示控制变得十分简单、自然。
基于此,软件工程的流行架构方式也在之前的 MVCMVP 之外,又多了一个 —— MVVM(Model-View-ViewModel)
数据绑定这种方式现在是如此的流行,以致于 Android 官方都出了一个 [Data Binding Library] (https://developer.android.com/topic/libraries/data-binding/index.html) 来支持数据绑定,但是由于成熟度等原因,目前还并没有成为主流,Android 中的主流视图显示方式,还是通过开发者手动给每个控件 set 数据。
—— 单从这一点上看,微信小程序的开发模式是比原生 Andorid 要『先进』一些的~ 😏

5. 页面的生命周期对比

小程序虽然是和前端 H5 页面一样是用 js 来开发,但是由于它最终运行的平台不再是浏览器,而是和 App 的表现几无二致,所以页面的生命周期也是和 App 差不多的。

一个小程序页面的典型生命周期如下:

  • onLoad :页面加载
  • onReady :初次渲染完成
  • onShow :页面显示
  • onHide :页面隐藏
  • onUnload :页面卸载

对比一下 Android 的 Activity 生命周期 :

  • onCreate :创建
  • onStart :开始(到前台)
  • onResume :显示
  • onPause :暂停(不再在前台)
  • onStop :隐藏
  • onDestory :销毁

微信小程序的页面生命周期稍微简单一些,但主要的思想跟 Activity 生命周期基本是一致的。

6. Debug对比

小程序的官方 IDE 是微信自己出品微信Web开发者工具,它内置了一个小程序的运行环境,本质上是基于 Chrome 内核的一个浏览器框架,算是一个模拟器了。
——它虽然跟 Android 的各种高大上的模拟器相比起来略显简陋,但是基本该有的功能也基本都有(断点、Log、网络监控等),而且由于是基于浏览器内核的页面 DOM 解析,所以运行的速度也是像浏览器打开网页一样流畅,不会像 Android 模拟器那样对系统资源要求很高。
另外,在绑定了开发者账号之后,也可以用手机进行真机调试来调试小程序,所以也能在上线前用不同的机器来进行充分的兼容性测试。

7. 总结

总体来说,小程序作为一个新的形态,从开发的角度,它可以算作是一个【Native开发】和【H5开发】的结合,它吸收了原生开发和 H5 开发的优点。对于前端开发人员和原生开发人员来说,都可以在微信小程序中找到许多熟悉的东西。再细节的许多点这里就不在赘述了,大家如果有兴趣,可以自己上手去体验一下。

综上,自然也就有两种人特别适合去做小程序的开发——H5的前端开发人员,以及之前的 Android/iOS 原生 App 开发者。

微信小程序的开发总体来说是很简单的。
—— 对于前端开发者来说,了解一下原生 App 的一些相关思想即可,这些工作其实只要读一遍小程序的开发者指南基本就差不多了。
—— 而对于原生开发者来说,只要稍微补一下 js 的相关知识(html/css),也基本就差不多可以上手去做了。如果你之前恰好已经有过一些 js 的使用经验,那就不用多说了,花半个小时看一下小程序的文档,直接上!


关于作者 :  
http: //www.barryzhang.com
https: //github.com/barryhappy
http: //www.jianshu.com/users/e4607fd59d0d


刚开了个公众号,用以分享Android相关的干货,求些关注,【不只Android】:
【不只Android】