深入小程序系列之三 ReactNative和小程序混编

Posted CNHK19

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入小程序系列之三 ReactNative和小程序混编相关的知识,希望对你有一定的参考价值。

背景

本文我们将开一下脑洞,在 ReactNative 工程基础上下集成及运行小程序方案。

先看一下效果如下:

 

 

环境搭建

npm install -g react-native-cli yarn

官方的环境搭建文档已经有详细的说明,这里不再重复。大家可以看下我本地的环境配置版本,目前整个项目运行稳定,可以借鉴。

$ react-native info
info Fetching system and libraries information...
System:
    OS: macOS 10.15.3
    CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
    Memory: 93.87 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 10.20.1 - ~/.nvm/versions/node/v10.20.1/bin/node
    Yarn: 1.22.4 - ~/.nvm/versions/node/v10.20.1/bin/yarn
    npm: 6.14.4 - ~/.nvm/versions/node/v10.20.1/bin/npm
    Watchman: Not Found
  Managers:
    CocoaPods: 1.9.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.4, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 26, 28, 29
      Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.0
      System Images: android-26 | Google Play Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 3.6 AI-192.7142.36.36.6241897
    Xcode: 11.4/11E146 - /usr/bin/xcodebuild
  Languages:
    Java: 10.0.1 - /Library/Java/JavaVirtualMachines/jdk-10.0.1.jdk/Contents/Home/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.11.0 => 16.11.0 
    react-native: 0.62.2 => 0.62.2 
  npmGlobalPackages:
    *react-native*: Not Found

新建 ReactNative 样例工程

新建 ReactNative 工程

react-native init mopdemo

稍等一会...

初始化项目完成之后,你可以选择两种不同的方式运行 App 在 iOS/Android 平台:

注意!ReactNative需要依赖本地安装对应的 iOS,Android 开发工具,即需要安装 Xcode 和 AndroidStudio。具体安装使用方法这里不赘述。

这里我们用 VSCode+Xcode 作为开发组合环境。

集成小程序解析引擎

这里我们采用凡泰集成免费社区版的小程序解析引擎,只需要 10 行代码量不到即可完成小程序集成。

  1. 引入小程序引擎插件。在 package.json 文件中引入小程序 ReactNative 插件
"react-native-mopsdk": "^1.0.1"
  1. 在 main.dart 文件中增加以下小程序引擎初始化方法。 Mop.instance.initialize 这里需要用到 sdkkey 和 secret。可以直接在https://mp.finogeeks.com免费注册获取。注册使用方法可以参考接入指引
import MopSDK from \'react-native-mopsdk\';
// 1. mop初始化
MopSDK.initialize(
    appkey: \'22LyZEib0gLTQdU3MUauASlb4KFRNRajt4RmY6UDSucA\',
    secret: \'4a915e447bcbd439\',
    apiServer: \'https://mp.finogeeks.com\',
    apiPrefix: \'/api/v1/mop\'
  , (data) => 
    console.log(\'message;\', data);
  );
  1. 打开小程序
MopSDK.openApplet(\'appid\',\'\',\'\',(data)=>);
  • SDKKEYSecret 可以从前面部署的社区版的管理后台获取。
  • apiServer 为这里是小程序生态后端的服务地址也就是前文所输入的IP:端口
  • 小程序id 为在管理后台上架的小程序唯一ID(在小程序小架时自动生成)
  • 上述的参数可以在前文服务器部署的后台界面上获取,亦可以在没有部署服务端的情况下在https://mp.finogeeks.com快速注册,免费获取。
  • 重要事情说三遍,您可以在官方的github仓库中查看示例代码 https://github.com/finogeeks/mop-react-native-demo

保姆级教程:写出自己的移动应用和小程序(篇二)

我们知道,App 的开发更偏向于用户层面,从 UI 展示到业务逻辑处理,全程处理用户的行为。而 SDK 面向的是开发者,开发更偏向于功能方面,注重功能的开发实现。

在本系列的上一篇文章中,我们重点学习了如何做出一个 iOS / Android 应用,今天,我们来试试编写一个SDK吧!

一、SDK是什么?

SDK 全称 Software Development Kit,广义上的 SDK 是为特定的软件包、软件框架、硬件平台、操作系统等建立应用程序时所使用的开发工具的集合(在 iOS 项目中,SDK 也被称为库)。

在 iOS 开发或 Android 开发中,不可避免会需要使用第三方工具提升产品的开发效率,比如用于消息推送的极光,用于第三方支付与登录的支付宝,微信等等。但大多数商用产品都不会直接给出源码(可能只有为爱发电的开源项目才会无私提供源码),而我们在开发 App 时就需要将这些第三方 SDK 集成在我们的项目之中。

SDK 的全称是 Software Development Kit,翻译过来是软件开发工具包,这是一种被用来辅助开发某类软件而编写的特定软件包。

二、SDK 设计的基本原则有哪些?

一款好用且设计充分的 SDK 必须要遵循以下 4 条基本原则,即:

  1. SDK 安全,稳定
  2. 统一的开发规范
  3. Library 小而精
  4. 不依赖第三方 SDK
  • 安全,稳定:考虑到 SDK 是需要嵌入到 App 里面去的,所以 SDK 最重要的特性就是安全性,不会因为乱开放接口而导致 App 数据泄露;其次重要的是 SDK 的稳定性, SDK 的 Crash 如果没有被捕获进行处理,则会导致应用彻底崩溃(这样就会导致第三方接入的 App 体验性非常差),甚至会直接导致接入方的用户流失;
  • 统一的开发规范:对于 SDK 开发规范来说,统一的命名规范很重要,最好的状态是“接入方看到接口命名就能知道是哪家厂商的 SDK”,换句话说就是 SDK 的命名规范统一,形成自己公司的品牌效应,此外也方便开发者进行接入使用。此外也需要具有自己的编码规范,你可以在网上找到大厂的规范模板,并通过借鉴整理出属于自己的规范,从而尽早统一代码风格;
  • Library 小而精:小是指要避免造成接入方的App增加很大,不然会引起接入方的不满,甚至下架。精是指功能要专注,比如极光推送,就是专注推送相关的功能;
  • 不依赖第三方 SDK:这个也很好理解,SDK 中如果又依赖其他第三方 SDK, 不仅会导致 SDK 的体积变大,也会影响接入方集成 SDK 的相关成本。

三、在 iOS 环境下如何开发 SDK

1. iOS 环境下的 SDK

如同上文所说,在 iOS 开发中,我们将 SDK 称为“库”,我们是这样对其定义的:

  1. 一般是给应用提供通用服务的,非独立运行的程序集合;
  2. 一般都是编译过的,方便使用。

我们会根据库的调用方法分为“静态库”和“动态库”两种:

  1. 静态连接:一般是指在创建应用程序的时候,将库集成进去,这样做的好处就是应用程序包自身可以独立运行,而不好的地方就是包会略显臃肿,库不能共享(静态库经常以 .a 结尾);
  2. 动态连接:创建应用的时候只约定好与库之间的调用关系,而不彻底将库包集成进应用。这样在应用运行时,需要运行环境中提供库,并且连接装载。优劣与静态库相反,动态链接库需要库环境,但由于本身不集成库内容,会比较小,同时也为和其他应用共享库的使用提供了可能(常见的动态库是 Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib/.tbd)。

特别注意:平时我们经常说的 Framework (in Apple) 是 Cocoa/Cocoa Touch 程序中使用的一种资源打包方式,可以将代码文件、头文件、资源文件、说明文档等集中在一起,方便开发者使用。也就是说我们的 Framework 其实是资源打包的方式,和静态库动态库的本质是没有什么关系。

2. 静态库和动态库的区别

如果说要找出静态库与动态库的区别,那可以从文件链接(每个源代码模块独立编译,然后按照需要将他们组装起来,这个组装模块的过程,就是链接)的角度进行解释:

  • 静态库:链接时会被完整的复制到可执行文件中,所以如果两个程序都用了某个静态库,那么每个二进制可执行文件里面,都会含有这份静态库的代码;
  • 动态库:链接时不复制,而是在程序启动后动态加载,然后再进行符号决议(符号绑定)。理论上动态库只存在一份就可以了。其他的程序都可以动态链接到这个动态库上面,从而节省内存(内存中只有一份动态库)。另外一个好处是,由于动态库并不绑定到可执行程序上,所以我们想升级这个动态库就很容易,windows和linux上面一般插件和模块机制都是这样实现的。

具体的优劣势可以看这张表:

库类型

优点

缺点

静态库

1. 目标程序没有外部依赖,直接就可以运行。 2. 效率较动态库高。

1. 会使用目标程序的体积增大。

动态库

1. 不需要拷贝到目标程序中,不会影响目标程序的体积。 2. 同一份库可以被多个程序使用(因为这个原因,动态库也被称作共享库)。 3. 编译时才载入的特性,也可以让我们随时对库进行替换,而不需要重新编译代码。实现动态更新

1. 动态载入会带来一部分性能损失(可以忽略不计) 2. 动态库也会使得程序依赖于外部环境。如果环境缺少动态库或者库的版本不正确,就会导致程序无法运行(Linux lib not found 错误)。

静态库可以简单理解为一堆目标文件(.o/.obj)的打包体(并非二进制文件),而动态库可以简单理解为 一个没有 main 函数的可执行文件。

3. 了解 iOS 的动态库(即被阉割的动态库)

有一个背景知识需要注意,iOS 官方规定不允许存在动态库,并且所有的 IPA 都需要经过 Apple 的私钥加密后才能用,即使你用了动态库也会因为签名错误而无法加载(越狱和非 App Store 除外)。于是这就把开发者自己开发动态库这件事变成为了天方夜谭。

iOS8 之前的 iOS 应用都是运行在沙盒当中的,不同程序之间不能共享代码,并且 iOS 又是单进程运行的(也就是某一时刻只有一个进程在运行),那么即使你写个共享库也无法共享给他人。

而动态下载代码又是被苹果官方明令禁止的,也就是说动态库的优势完全无法发挥,所以动态库也就没有存在的必要了。

但是这一切问题都随着 iOS8 发布之后的 App Extesion 特性, Swift 的诞生发生了奇妙的改变。

由于 iOS 主 App 需要和 Extension 共享代码,Swift 语言机制也需要动态库,于是苹果后来提出了 Embedded Framework,这种动态库允许 APP 和 App Extension 共享代码(动态库的生命被限定在一个APP进程内)。

更简单的解释:虽然提供了动态库,但这是被阉割的动态库。

尽管如此,这种动态库(Embedded Framework) 和系统的 UIKit.Framework 还是有很大区别的。传统的动态库是给多个进程使用的,而这里的动态库(Embedded Framework)是给单个进程里面多个可执行文件用的。

系统的 Framework 不再需要拷贝到目标程序中,我们自己做出来的动态库(Embedded Framework) 哪怕是动态的,最后也还是要拷贝到 App 中(App 和 Extension 的 Bundle 是共享的)。所以苹果没有直接把这种 Embedded Framework称作动态库而是叫 Embedded Framework。

上面提到的 Swift 也有原因,在 Swift 的项目中如果要在项目中使用外部代码,可选的方式只有两种,一种是把代码拷贝到工程中,另一种是用动态 Framework。使用静态库是不支持的

这个问题的根本原因是, Swift 的运行库没有被包含在 iOS 系统中,反而会被打包进 App 中(这也是造成 Swift App 体积大的原因),静态库会导致最终的目标程序中包含重复的运行库。

4. 以动态库为例,开始制作SDK

第一步:创建 App 工程,命名为 RealDemo

保姆级教程:写出自己的移动应用和小程序(篇二)_移动应用

如果不清楚怎么创建,可以点击 ​​这里​

第二步:关闭 RealDemo 工程,然后在 RealDemo 目录下创建 Framework 工程,命名为 RealSDK

保姆级教程:写出自己的移动应用和小程序(篇二)_android_02

选择下方的 Framework 进行创建

保姆级教程:写出自己的移动应用和小程序(篇二)_sdk_03

切记目录不要选择错误

第三步:设置 Framework 工程的 Build Settings

保姆级教程:写出自己的移动应用和小程序(篇二)_sdk_04

创建动态库需要选择 Dynamic Library,如果要制作静态库则要选择 Static Library

第四步:关闭RealSDK工程,创建 WorkSpace,命名为 RealDemo

保姆级教程:写出自己的移动应用和小程序(篇二)_小程序_05

逐次点击 File - New - Workspace

保姆级教程:写出自己的移动应用和小程序(篇二)_小程序_06

创建后会出现对应的 workspace 文件

第五步:连接 Framework 工程和 App 工程

我们需要先打开 RealDemo.xcworkspace,打开后你会发现这里空空如也。

然后我们直接把需要连接的 Framework 工程(RealSDK.xcodeproj)和 App 工程(RealDemo.xcodeproj)拖进来就可以了!

保姆级教程:写出自己的移动应用和小程序(篇二)_ios_07

直接拖拽进 Xcode 即可

保姆级教程:写出自己的移动应用和小程序(篇二)_小程序_08

拖拽后你会发现两者的层级关系相同

第六步:把 Framework 添加到 App 工程中

保姆级教程:写出自己的移动应用和小程序(篇二)_小程序_09

逐次点击,不要点错了

保姆级教程:写出自己的移动应用和小程序(篇二)_小程序_10

选择前面创建的 framework

有过 SDK 开发经验的同学到这里应该已经看明白了,所谓实时联调说白了就是用 WorkSpace 把两个工程连接起来而已,跟 Pod 的原理有几分相似。

第七步:给 Framework 加点功能

我们需要增加一个 RealDog 类,定义一个 eat 方法,实现里面打印一句话“吃骨头”。然后修改 RealDog.h 的 Target Membership 为 Public,意思为公开头文件。

保姆级教程:写出自己的移动应用和小程序(篇二)_移动应用_11

在这里我定义了 eat 方法

RealDog的实现如下:

@implementation RealDog

+ (void)eat
NSLog(@"吃骨头");

@end

第八步:在 App 的 ViewController 调用一下 SDK 的方法

#import "ViewController.h"
#import <RealSDK/RealDog.h>

@implementation ViewController

- (void)viewDidLoad
[super viewDidLoad];
[RealDog eat];


@end

第九步:运行一下,可以发现App工程成功调用了SDK的方法

保姆级教程:写出自己的移动应用和小程序(篇二)_小程序_12

OK,实时联调到此结束

5. 使用脚本合并真机、模拟器等多种架构的 Framework

第一步:添加一个 Aggregate Target

保姆级教程:写出自己的移动应用和小程序(篇二)_sdk_13

RealSDK Project -> TARGETS -> "+"(左下角) -> Cross-platform - Other -> Aggregate

第二步:将 Aggregate Target 命名为“RealSDK-Script”

保姆级教程:写出自己的移动应用和小程序(篇二)_sdk_14

命名后点击 Finish 即可

第三步:依赖 RealSDK

保姆级教程:写出自己的移动应用和小程序(篇二)_小程序_15

在 Dependencies 中配置依赖关系

第四步:添加脚本

保姆级教程:写出自己的移动应用和小程序(篇二)_ios_16

点击这里的 New Run Script Phase

保姆级教程:写出自己的移动应用和小程序(篇二)_移动应用_17

复制下方脚本即可

这个脚本是通用的,各位同学直接复制粘贴即可:

# Type a script or drag a script file from your workspace to insert its path.
UNIVERSAL_OUTPUTFOLDER=../Framework/

# 创建输出目录,并删除之前的framework文件
mkdir -p "$UNIVERSAL_OUTPUTFOLDER"
rm -rf "$UNIVERSAL_OUTPUTFOLDER/$PROJECT_NAME.framework"

# 分别编译模拟器和真机的Framework
xcodebuild -target "$PROJECT_NAME" ONLY_ACTIVE_ARCH=NO -configuration $CONFIGURATION -sdk iphoneos BUILD_DIR="$BUILD_DIR" BUILD_ROOT="$BUILD_ROOT" clean build
xcodebuild -target "$PROJECT_NAME" ONLY_ACTIVE_ARCH=NO -configuration $CONFIGURATION -sdk iphonesimulator BUILD_DIR="$BUILD_DIR" BUILD_ROOT="$BUILD_ROOT" clean build

# 定义真机、模拟器Build文件夹路径变量
IPHONE_BUILD=$BUILD_DIR/$CONFIGURATION-iphoneos/$PROJECT_NAME.framework
SIMULATOR_BUILD=$BUILD_DIR/$CONFIGURATION-iphonesimulator/$PROJECT_NAME.framework

# 拷贝framework到univer目录
cp -R "$IPHONE_BUILD" "$UNIVERSAL_OUTPUTFOLDER/"

#cp -R "$SIMULATOR_BUILD" "$UNIVERSAL_OUTPUTFOLDER/"

# 定义输出路径变量
OUTPUT_PATH=$UNIVERSAL_OUTPUTFOLDER/$PROJECT_NAME.framework

# 合并framework,输出最终的framework到build目录
lipo -create "$IPHONE_BUILD/$PROJECT_NAME" "$SIMULATOR_BUILD/$PROJECT_NAME" -output "$OUTPUT_PATH/$PROJECT_NAME"

第五步:运行脚本

保姆级教程:写出自己的移动应用和小程序(篇二)_sdk_18

依然是点击左侧的播放按钮

第六步:查看结果

保姆级教程:写出自己的移动应用和小程序(篇二)_android_19

能看到这个文件夹就代表编译成功啦!

如果你的 Mac 是最新的 M1芯片,那么可能会出现以下报错:

fatal error: lipo: /Users/hujianhui/Library/Developer/Xcode/DerivedData/RealDemo-ckvcidkkuvgpadeiqrvgjdyikcdc/Build/Products/Debug-iphoneos/RealSDK.framework/RealSDK and /Users/hujianhui/Library/Developer/Xcode/DerivedData/RealDemo-ckvcidkkuvgpadeiqrvgjdyikcdc/Build/Products/Debug-iphonesimulator/RealSDK.framework/RealSDK have the same architectures (arm64) and cant be in the same fat output file

你只需要去除 iOS 模拟器的 arm64 架构即可,方法如下:

保姆级教程:写出自己的移动应用和小程序(篇二)_移动应用_20

点击 arm64 前面的减号即可

6. 小贴士

  1. Framework 中使用 Category

在 Framework 工程的 Build Setting 中添加 -ObjC。另外,使用我们 SDK 的 App 的 Build Setting 中也要添加 -ObjC。

  1. Framework 支持 bitcode

保姆级教程:写出自己的移动应用和小程序(篇二)_移动应用_21

保姆级教程:写出自己的移动应用和小程序(篇二)_小程序_22

四、在 Android 环境中如何开发 SDK

1. Android SDK 介绍

Android App 集成第三方 SDK 的文件类型,主要有三种,一种是 JAR 包文件,和 SO 文件 ,另外一种是 AAR 文件, JAR 包是 Java 提供的 SDK 文件类型,里面包含的是纯 Java 编译过后的代码。SO 一般是 C 和 C++ 打包成库的文件。

AAR 名字来源于 Android Archive,见名知义,是一个 Android 库项目的二进制归档文件,使用 Android Studio ,非常简单可以生成一个 AAR 文件。AAR 库文件里面,包含了 JAR 和 SO,还有资源 Res 等文件,结构等同一个 App。

它可以提供构建应用所需的一切内容,包括源代码、资源文件和 Android 清单。不过,Android 库将编译为您可以用作 Android 应用模块依赖项的 Android ARchive (AAR) 文件,而不是编译为在设备上运行的 APK。

与 JAR 文件不同,AAR 文件会为 Android 应用提供以下功能:

  • AAR 文件可以包含多项 Android 资源和一个清单文件,让您除了能够在 Java 类和方法中进行捆绑以外,还能够在布局和可绘制对象等共享资源中进行捆绑;
  • AAR 文件可以包含 C/C++ 库,供应用模块的 C/C++ 代码使用。

2. 创建 SDK 工程

打开上个章节我们创建的示例工程,在工程上创建一个 library module,命名为GPush,让我们模拟实现一个推送简短新闻的接口。

保姆级教程:写出自己的移动应用和小程序(篇二)_移动应用_23

如果你忘记怎么做的话,可以点 ​​这里​

保姆级教程:写出自己的移动应用和小程序(篇二)_小程序_24

选择 Android Library,并在名称中输入 GPush

保姆级教程:写出自己的移动应用和小程序(篇二)_sdk_25

添加成功后我们会在左侧看到对应的 Libray 文件

3. 添加依赖项

如需在同一项目中的另一个应用或库模块中使用新的 Android 库代码,就需要这样添加一个项目级依赖项:

  1. 依次转到File > Project Structure > Dependencies;
  2. 选择要在其中使用库的模块;
  3. Declared Dependencies标签页中,点击 +,然后在下拉菜单中选择Module Dependency

保姆级教程:写出自己的移动应用和小程序(篇二)_sdk_26

先点击加号,再选中对应的 Module Dependency

保姆级教程:写出自己的移动应用和小程序(篇二)_sdk_27

将其加入依赖中

4. 接口设计

既然是做一个推送新闻的接口,那就必须要分为客户端和推送端,即 Client#onReceiveMessage 和 GPush#pushMessage。

从下面给出 UML 图可以看出,只需要一个方法就可以监听到新闻推送了,GPushImpl#start(Client client)。

保姆级教程:写出自己的移动应用和小程序(篇二)_ios_28

可以看我画的 UML 图,帮助你更进一步理解

GPush 类

package com.myname.library;
interface GPush
void pushMessage(String msg);

GPushImpl 类

package com.myname.library;

import android.os.Handler;
import android.os.HandlerThread;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

public class GPushImpl implements GPush

private List<Client> mClients;
private HandlerThread mHandlerThread;
private Handler mHandler;
private Random mRandom = new Random();
private List<String> msgs = new ArrayList<String>()

add("1、文旅部:严查以中老年为目标的包价游产品");
add("2、加快推进沿长江户籍改革,服务长江经济带高质量发展。");
add("3、今年首批10家非法社会组织网站被关停,含中国文艺名人协会等。");
add("4、上海:5月1日起,电动自行车骑乘人员必须戴头盔。");
add("5、广州:清明祭扫实行实名预约,倡导网上祭扫、错峰延后祭扫。");
add("6、河北武安铁矿致6死事故涉嫌瞒报,企业相关人员被控制。");
add("7、黄峥辞任拼多多董事长:将放弃超级表决权,投入科学研究。");
add("8、打破国外20年垄断,国产人工心脏研发成功,但商用落地时间暂不确定。");
add("9、调查:六成青年入睡时间晚于23点,梦多睡眠浅成年轻人睡眠主要问题。");

;

GPushImpl()
mClients = new ArrayList<>();
mHandlerThread = new HandlerThread("Push-Thread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());


@Override
public void pushMessage(String msg)
Iterator<Client> iterator = mClients.iterator();
while (iterator.hasNext())
iterator.next().onReceiveMessage(msg);



public static void start(Client client)
GPushImpl gPush = new GPushImpl();
gPush.mClients.add(client);
gPush.mHandler.post(gPush.mRunnable);


private Runnable mRunnable = new Runnable()

@Override
public void run()
mHandler.postDelayed(mRunnable, mRandom.nextInt(10000));
pushMessage(msgs.get(mRandom.nextInt(msgs.size())));

;

Client 类

public interface Client 
void onReceiveMessage(String msg);

开始监听新闻推送

GPushImpl.start 
Toast.makeText(MainActivity@this,it,Toast.LENGTH_LONG).show()

SDK 打包

./gradlew :GPush:assembleRelease

保姆级教程:写出自己的移动应用和小程序(篇二)_android_29

打包完成后就行生成一个 aar 文件, 这个文件就是我们打包的结果了

5. 最后注意事项 — 混淆

基于代码保护的目的,Gradle 打包默认会根据 build.gradle 和 ​​proguard-rules.pro​​ 配置的混淆规则,来对代码进行一个混淆, 如果 library 里面使用了如 GSON 或者反射等技术则需要对部分类进行 keep 操作。

buildTypes 
release
minifyEnabled false
proguardFiles getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro

-keep class com.myname.library.** *;


如果正确按照教程,那相信你已经成功的做出了属于自己的第一个 iOS 与 Android SDK,本期教程依然基于 mac 电脑进行实现,如果你的电脑是 Windows 或者其他操作系统,还需要进行一些其他的灵活配置。

在下一期的文章中,我们将会一起聊聊如何引入 SDK ,敬请期待。 更多信息可进入FinClip官网查看

以上是关于深入小程序系列之三 ReactNative和小程序混编的主要内容,如果未能解决你的问题,请参考以下文章

深入小程序系列之Flutter 和小程序混编

深入小程序系列之二Flutter 和小程序混编

有手就行系列:让每个人都能写出自己的移动应用和小程序

深入理解计算机系统(第二版)----之三:程序的机器级表示

保姆级教程:写出自己的移动应用和小程序(篇四)

保姆级教程:写出自己的移动应用和小程序(篇八)