前言      

       相信越来越多小伙伴发现不少超级APP的页面都采用小程序开发了。例如支付宝客户端,首页有一个小程序中心的入口,支付宝上很多页面都是小程序了。


android小程序 android小程序容器开发_hybird

图1 支付宝小程序入口

       第一次打开的一个新功能时,会出现一个短暂的loading过程。小程序右上角有查看详情和关闭的按钮,例如中国体育小程序。

图2 支付宝“中国体育”小程序截图

       那么为什么越多越多大厂的app采用了小程序容器化开发呢?博主将在本博客简要说明小程序容器化的趋势、优点,以及如何基于uni-app在Android端开发自己的小程序。本文提纲如下:


android小程序 android小程序容器开发_android_02

图3 博客提纲

 一. 小程序趋势

       回到前言提到的问题——那么为什么越多越多大厂的app采用了小程序容器化开发呢?这是大前端发展的趋势。博主认为主要有以下几个原因:

1.1多端一致性

        Android/iOS双端一致性,一直是移动端致力解决的问题。一些热门产品,通常还有PC端、公众号、H5页面等门户产品。在博主的项目中就要求四端:Android、iOS、PC端、H5提供交易功能。同样的功能,实现了四遍,测试四遍。跨平台技术是保证多端一致性的重要手段。

1.2 动态化

        动态化,不仅可以满足千人千面的需求,通过后台配置模版实现页面动态化,不需要客户端coding大量的代码;还可以减少app发版的次数和降低上架时间,日渐严格的苹果市场审核机制让开发者意识到动态化的重要性,尤其是出现BUG时需要紧急发版。对于强监管业务,app也是需要具备随时下架某个功能的能力。

1.3 低代码,提升开发效率

       low- code——低代码,这在业界已经流行好多年了。low- code可以大幅度减少代码量,通过模版代码就能快速满足功能开发或支持第三方接入的需求。同一套模版代码还可以复用到各个端,开发量减少了,测试时间也减少了,开发效率得到极大的提升。

1.4 安装包控制

       大厂的超级app通常包罗很多功能,还是拿支付宝来说,支付宝上面的多功多得数不清。如果用纯原生的代码来实现,想想app安装包会大到什么程序?这对app推广非常不利的。所以,控制 app安装包大小,web或小程序化就变成非常重要了 。

二. 为什么选择uni-app

       市面上能满足开发并集成自己的小程序的技术还挺多的,例如AntBuilder、FinClip、uni-app等。没有最好的技术,只有适合自己团队和业务场景的技术才是最佳的技术,所以博主不会展开讨论它们的区别,而是从自身的角度谈谈为什么选择uni-app。

2.1 技术栈

       uni-app技术栈还是基于vue.js + weex的,比较符合我们团队的技术储备的情况,学习成本非常低,团队能快速上手。

2.2 uni-app的特点

       uni-app从2018年发布第一个版本以来,一直保持快速迭代的趋势[1] 。官方github上star数量为:32.7K[2]。uni-app在开发者数量、案例、跨端抹平度、扩展灵活性、性能体验、周边生态、学习成本、开发成本等关键指标上拥有更强的优势[3]。

1)开发者/案例数量更多:数百万应用、uni统计月活12亿、70+微信/qq群、更高的百度指数,跨端完善度高。

2)平台能力不受限:在跨端的同时,通过条件编译+平台特有API调用,可以优雅的为某平台写个性化代码,调用专有能力而不影响其他平台。支持原生代码混写和原生sdk集成。

3)性能体验优秀:加载新页面速度更快、自动diff更新数据。App端支持原生渲染,可支撑更流畅的用户体验。小程序端的性能优于市场其他框架。

4)周边生态丰富:插件市场数千款插件。支持NPM、支持小程序组件和SDK。微信生态的各种sdk可直接用于跨平台App。

5)学习成本低:基于通用的前端技术栈,采用vue语法+微信小程序api,无额外学习成本。

6)开发成本低: HBuilderX是高效开发神器,熟练掌握后研发效率至少翻倍。

三. 集成uni-app

  3.1 安装环境

       环境安装参考官网[4],uni-app支持通过可视化界面、vue-cli命令行两种方式快速创建项目。推荐大家使用可视化界面。可视化的方式比较简单,HBuilderX内置相关环境,开箱即用,无需配置nodejs。

       开始之前,开发者需先下载安装HBuilderX IDE工具:

        HBuilderX是通用的前端开发工具,但为uni-app做了特别强化。分两个版本:1)App开发版,可开箱即用;2)标准版,在运行或发行uni-app时,会提示安装uni-app插件,插件下载完成后方可使用。推荐下载App开发版,博主安装的MacOS 开发版。


android小程序 android小程序容器开发_android_03

图3.1 HBuilderX安装包

  •  下载SDK:从官网下载最新版本的SDK[5], 下载链接。如下图所示:

android小程序 android小程序容器开发_hybird_04

图3.2 下载SDK

   3.2 集成 SDK

  •    添加依赖

          1)在app的build.gradle添加7步配置:

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

//1.必须配置
def mfph = [
        //宿主包名
        "apk.applicationId" : "com.rzl.uniapp.android",
]

android {
    compileSdkVersion 30
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.rzl.uniapp.android"
        minSdkVersion 21 // 2. 改为21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        // 3. 添加以下配置
        multiDexEnabled true
        manifestPlaceholders = mfph
        ndk {
            abiFilters 'x86','armeabi-v7a',"arm64-v8a" //不支持armeabi
        }

        //4. 此处配置必须添加 否则无法正确运行
        aaptOptions {
            additionalParameters '--auto-add-overlay'
            //noCompress 'foo', 'bar'
            ignoreAssetsPattern "!.svn:!.git:.*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~"
        }
    }

    // 5. 导入aar需要的配置
    repositories {
        flatDir {
            dirs 'libs'
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    //6. 导入SDK相关依赖jar、aar
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation fileTree(include: ['*.aar'], dir: 'libs')

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    // 7. 添加依赖库
    implementation 'com.android.support:recyclerview-v7:28.0.0' //必须集成
    implementation 'com.android.support:support-v4:28.0.0' //必须集成
    implementation 'com.android.support:appcompat-v7:28.0.0' //必须集成
    implementation 'com.alibaba:fastjson:1.1.46.android' //必须集成
    implementation 'com.facebook.fresco:fresco:1.13.0'//必须集成
    implementation 'com.facebook.fresco:animated-gif:1.13.0'//必须集成
    implementation 'com.github.bumptech.glide:glide:4.9.0'//必须集成
}

2)将sdk libs下的库(用到什么库添加什么)拷贝到app的libs下面:


android小程序 android小程序容器开发_hybird_05

图3.3 依赖的SDK libs

  •  SDK初始化:

   1)添加application,在application中添加初始化代码:

package com.rzl.uniapp.android

import android.app.Application
import io.dcloud.feature.sdk.DCUniMPSDK
import java.util.*
import io.dcloud.feature.sdk.DCSDKInitConfig
import io.dcloud.feature.sdk.MenuActionSheetItem


class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        // sdk初始化代码
        val sheetItems: List<MenuActionSheetItem> =
            ArrayList<MenuActionSheetItem>()
        val config: DCSDKInitConfig = DCSDKInitConfig.Builder()
            .setCapsule(true)
            .setMenuDefFontSize("16px")
            .setMenuDefFontColor("#ff00ff")
            .setMenuDefFontWeight("normal")
            .setMenuActionSheetItems(sheetItems)
            .build()

        DCUniMPSDK.getInstance().initialize(this, config)
    }
}

 2)新建一个assets目录,在asset目录下面创建apps文件夹,并拷贝SDK assets的data文件夹及js文件到assets目录下。


android小程序 android小程序容器开发_hybird_06

图3.4 创建assets及相关目录

 3)加载测试小程序

       从SDK的官方demo拷贝一个小程序到assets/apps下面,例如博主拷贝了:__UNI__2108B0A夹放到apps下面。  通过以下方法启动小程序。

      // 启动测试小程序
        try {
            DCUniMPSDK.getInstance().startApp(applicationContext, "__UNI__2108B0A")
        } catch (e: Exception) {
            e.printStackTrace()
        }

点击Android stdio的运行按钮之后,测试小程序被加载进来了。说明环境全部都OK,接下来可以编写自己的小程序了。

四. 编写并运行自己的小程序

  4.1 编写小程序

  • 打开HBuilderX,文件->新建->项目,项目信息如下:

android小程序 android小程序容器开发_android_07

图4.1 HBuilderX创建项目界面

创建好目录之后,我们来看看工程的代码结构。


android小程序 android小程序容器开发_android_08

图4.2 工程的代码结构

 1)pages:页面布局写在这下面;

 2)manifest.json:小程序的配置文件,选择性配置一些信息,如下图所示。前提:你需要到dcloud开发者中心官网注册一个账号,注册地址。在后台创建一个应用,如下图所示。


android小程序 android小程序容器开发_大前端_09

图3.7 dcloud开发者中心后台应用列表截图

android小程序 android小程序容器开发_大前端_10

图4.3 manifest.json配置图

3)pages.json:页面路由配置及全局样式。例如:

{
     "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
         {
             "path": "pages/about/about",
             "style": {
                 "navigationBarTitleText": "关于"
             }
         }
     ],
     "globalStyle": {
         "navigationBarTextStyle": "black",
         "navigationBarTitleText": "关于",
         "navigationBarBackgroundColor": "#F8F8F8",
         "backgroundColor": "#F8F8F8"
     }
 }

  4.2 运行小程序   

     点击HBuilderX左上角的运行按钮,选择编译设备,例如chrome浏览器。 


android小程序 android小程序容器开发_uni-app_11

图4.4 HBuilderX编译选择界面

  4.3 打包小程序

  • 代码运行没有问题,就可以打包了。打开HBuilderX,点击左上角的发行按钮,生成wgt包 。

android小程序 android小程序容器开发_大前端_12

图4.5 HBuilderX打包界面

4.4 集成小程序

  1)在app的assets/apps下面:创建__UINI__XX目录(XX是小程序的appID);再在__UINI__XX下面创建www目录。

2)将wgt重命名zip包,解压缩,将压缩包的内容拷贝到assets/apps/__UINI__XX/www文件夹下面。


android小程序 android小程序容器开发_android_13

图4.6 拷贝小程序文件示意图

4.5 运行小程序

     在调起小程序的入口,将名字改为我们的小程序名称即可。调起方法如下:

// xx是小程序appIDDCUniMPSDK.getInstance().startApp(applicationContext, "__UNI__xx")

在Android studio中代码,看到我们的小程序被加载进来了。 


android小程序 android小程序容器开发_uni-app_14

图4.7 小程序加载页面

5.Demo代码

     demo代码上传到github,如果需要,请小伙伴自行下载。下载地址

6.参考链接

[1] https://uniapp.dcloud.io/release?id=_014520180728-alpha

[2] https://github.com/dcloudio/uni-app

[3] https://uniapp.dcloud.io/README

[4] https://uniapp.dcloud.io/quickstart-hx

[5]https://nativesupport.dcloud.net.cn/UniMPDocs/SDKDownload/android