移动端原生框架对比评测

移动端开发技术知识库

一、技术分类总览

按渲染方式和技术架构,分为四大阵营:

阵营 代表技术 渲染方式 性能
自绘引擎 Flutter 自带渲染引擎,直接绘制像素 ⭐⭐⭐⭐⭐
原生组件映射 React Native 映射到原生组件 ⭐⭐⭐⭐
WebView + 原生桥接 Ionic / Cordova / PhoneGap WebView 渲染 HTML/CSS/JS ⭐⭐
WebView 套壳 H5 套壳 纯 WebView,无桥接 ⭐

二、各技术详解

2.1 Flutter(自绘引擎)

  • 原理:自带 Skia 渲染引擎,不依赖平台原生组件,直接在 Canvas 上绘制像素
  • 优点:性能最接近原生,UI 一致性极好(各平台看起来完全一样)
  • 缺点:包体积大(引擎约 5-10MB),Dart 语言生态相对小,无法直接使用原生组件
  • 适用:对性能和 UI 一致性要求高的应用

2.2 React Native(原生组件映射)

  • 原理:JS 写 UI → 通过 Bridge 转换 → 调用平台原生组件渲染
  • 优点:使用原生组件,体验接近原生;JS 生态丰富;新架构 Fabric + TurboModules 大幅提升性能
  • 缺点:Bridge 通信有开销;复杂动画性能不如 Flutter;需要了解原生开发知识
  • 适用:已有 JS/React 技术栈的团队

2.3 Ionic / Taro / UniApp(跨端框架)

Ionic
  • 本质:WebView 渲染 + Capacitor/Cordova 提供原生 API 桥接
  • 技术栈:Angular/React/Vue + HTML/CSS/JS
  • 特点:本质还是 WebView 渲染,但通过桥接可以调用原生 API
Taro(京东出品)
  • 本质:一套代码编译到多端(小程序、H5、RN)
  • 技术栈:React/Vue 语法 → 编译到各端
  • 特点:核心优势是跨小程序端(微信/支付宝/百度等),不是追求原生性能
UniApp(DCloud 出品)
  • 本质:类似 Taro,一套代码编译到多端
  • 技术栈:Vue 语法 → 编译到各端
  • 特点:生态更完善,插件市场丰富;App 端底层用 WebView + weex(部分原生渲染)

Taro 和 UniApp 的核心价值:不是"高性能 App",而是"一套代码跑小程序 + H5 + App",解决的是多端维护成本问题。

2.4 Cordova / PhoneGap(WebView + 原生桥接)

  • 原理 :

    arduino 复制代码
    HTML/CSS/JS(WebView 渲染)
         ↕ JavaScript Bridge
    原生 API(相机、GPS、文件系统等)
  • Cordova:Apache 开源项目,提供原生 API 插件机制

  • PhoneGap:Adobe 出品,本质是 Cordova 的发行版(已停止维护)

  • 核心机制 :通过 cordova.exec() 调用原生插件,插件用 Java/ObjC 写,JS 端通过 Bridge 调用

2.5 H5 套壳(纯 WebView 包装)

  • 原理 :

    css 复制代码
    原生 App(壳)→ 只有一个 WebView 组件 → 加载远程/本地 HTML
  • 本质:就是一个原生 App 里放了一个全屏浏览器,加载你的网页

  • 实现方式 :

    • Android:一个 Activity + WebView
    • iOS:一个 UIViewController + WKWebView

三、H5 套壳 vs Cordova 的区别

对比项 H5 套壳 Cordova
渲染方式 WebView WebView(一样)
渲染性能 一样慢 一样慢
原生 API 访问 ❌ 默认不能 ✅ 通过插件桥接
JS 调原生能力 无桥接机制 有 cordova.exec() Bridge
插件生态 无 丰富的插件市场
开发复杂度 极低(10行代码) 低(需配置 Cordova 项目)
本质区别 纯壳,无通信 壳 + 通信桥接

H5 套壳能使用原生 API 吗?

默认不能。纯 H5 套壳就是:

  • WebView 里的 JS 只能调用浏览器标准 API(navigator.geolocation 等)
  • 无法调用相机、推送、蓝牙、通讯录等原生能力
  • 除非自己写桥接(类似自己实现一个简化版 Cordova)

如果想在 H5 套壳里调用原生 API,有两条路:

  1. 自己写 JS Bridge:原生端注册 handler,JS 端通过 window.webkit.messageHandlers(iOS)或 WebView.addJavascriptInterface(Android)通信
  2. 直接用 Cordova:它已经帮你做好了这件事

Cordova 本质上 = H5 套壳 + 原生 API 桥接 + 插件生态


四、WebView、Bridge、桥接能力

4.1 WebView 是什么?

WebView 就是移动端操作系统内嵌的一个"浏览器内核组件"。

ini 复制代码
Chrome 浏览器 = 地址栏 + 标签页 + 书签 + 前进后退按钮 + 渲染引擎
WebView     = 只有渲染引擎(去掉浏览器外壳)

各平台的 WebView:

平台 WebView 组件 底层内核
Android android.webkit.WebView Chromium(4.4+)
iOS WKWebView WebKit(Safari 同内核)
鸿蒙 Web 组件 Chromium 内核

代码层面的理解(Android):

xml 复制代码
<WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
java 复制代码
WebView webView = findViewById(R.id.webview);
webView.loadUrl("https://www.baidu.com");
webView.loadUrl("file:///android_asset/index.html");

iOS 端:

swift 复制代码
let webView = WKWebView(frame: view.bounds)
webView.load(URLRequest(url: URL(string: "https://www.baidu.com")!))
view.addSubview(webView)

WebView 能做什么:

  • ✅ 渲染 HTML/CSS/JS(和浏览器一模一样)
  • ✅ 加载远程 URL 或本地 HTML 文件
  • ✅ 执行 JavaScript 代码
  • ❌ 默认不能调用原生 API(相机、GPS、推送等)
  • ❌ 没有浏览器地址栏、导航栏等 UI

4.2 Bridge 是什么?

Bridge(桥)是 WebView 里的 JS 和原生代码之间通信的通道。

为什么需要 Bridge:

diff 复制代码
你的 H5 页面里有一个按钮:"拍照上传"

JS 想做的事:调用手机摄像头 → 拍照 → 拿到照片 → 上传

问题:
- JS 运行在 WebView 里(浏览器环境)
- 浏览器环境没有"调用摄像头"这个原生 API
- 摄像头 API 只存在于原生代码中(Java/Kotlin/Swift)

JS 和原生代码,就像隔了一条河的两个岛,互不相通
arduino 复制代码
┌─────────────────┐          ┌─────────────────┐
│   WebView 岛     │    河    │   原生岛          │
│                 │ ←无法通信→ │                 │
│  JS 代码        │          │  Java/Swift 代码  │
│  想调摄像头 ❌    │          │  有摄像头 API ✅   │
└─────────────────┘          └─────────────────┘

                    ↓ 加 Bridge ↓

┌─────────────────┐          ┌─────────────────┐
│   WebView 岛     │          │   原生岛          │
│                 │  Bridge  │                 │
│  JS 代码        │ ════════ │  Java/Swift 代码  │
│  调用摄像头 ✅    │  通信通道  │  有摄像头 API ✅   │
└─────────────────┘          └─────────────────┘

Bridge 支持双向通信:

arduino 复制代码
方向1:JS → 原生(JS 调用原生能力)
  JS: "帮我打开摄像头"
  → Bridge 传递消息 →
  原生: 打开摄像头,返回照片

方向2:原生 → JS(原生通知 JS)
  原生: "收到一条推送通知"
  → Bridge 传递消息 →
  JS: 在页面上显示通知

Bridge 的底层实现:

Android 端(方式1:addJavascriptInterface):

java 复制代码
webView.addJavascriptInterface(new Object() {
    @JavascriptInterface
    public void openCamera() {
        // 调用原生摄像头
    }
}, "NativeBridge");
// JS 端:window.NativeBridge.openCamera()

Android 端(方式2:prompt 拦截):

java 复制代码
webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsPrompt(WebView view, String url, String message,
                              String defaultValue, JsPromptResult result) {
        if (message.equals("openCamera")) {
            openCamera();
            result.confirm("success");
            return true;
        }
        return false;
    }
});
// JS 端:prompt("openCamera")

iOS 端:

swift 复制代码
// 原生 → JS 调用
let contentController = WKUserContentController()
contentController.add(self, name: "NativeBridge")
// JS 端:window.webkit.messageHandlers.NativeBridge.postMessage("openCamera")

// 原生调 JS
webView.evaluateJavaScript("onPhotoReceived('photo_base64')")

Bridge 通信的数据格式(通常使用 JSON):

json 复制代码
{
  "method": "openCamera",
  "params": { "quality": "high", "maxSize": 1024 },
  "callbackId": "cb_001"
}
json 复制代码
{
  "callbackId": "cb_001",
  "status": "success",
  "data": { "photoPath": "/path/to/photo.jpg" }
}

4.3 桥接能力是什么?

桥接能力 = 通过 Bridge 暴露给 JS 调用的原生功能的集合。

能力分类 具体功能 JS 原生能做吗 需要桥接吗
设备信息 获取设备型号、系统版本 ❌ ✅
相机 拍照、录像、扫码 ❌ ✅
地理位置 GPS 定位 部分(精度低) ✅
文件系统 读写本地文件 ❌ ✅
推送通知 发送/接收通知 ❌ ✅
蓝牙 连接蓝牙设备 ❌ ✅
通讯录 读取联系人 ❌ ✅
生物识别 指纹/面容识别 ❌ ✅

不同框架的桥接能力:

arduino 复制代码
H5 套壳:     无桥接能力(除非自己写)
Cordova:     丰富的插件生态(1000+ 插件)
Ionic:       使用 Capacitor(Cordova 的现代替代)
React Native:自有 Bridge + TurboModules
Flutter:     Platform Channel(自研桥接机制)

4.4 完整调用流程示例(拍照上传)

arduino 复制代码
用户点击 H5 页面的"拍照"按钮
        │
        ▼
JS 调用:window.NativeBridge.call('openCamera', {quality: 'high'})
        │
        ▼ Bridge 传递
        │
原生端收到消息:解析 method = "openCamera"
        │
        ▼
原生调用系统 API:Camera.open() → 拍照 → 获取照片
        │
        ▼ Bridge 回传
        │
JS 收到回调:callback({photoPath: "/path/to/photo.jpg"})
        │
        ▼
JS 将照片显示在页面上 / 上传到服务器

三者关系:WebView(载体)+ Bridge(通道)+ 桥接能力(功能)= 混合开发 App


五、Swift 原生 vs Flutter vs React Native

5.1 本质区别

arduino 复制代码
Swift 原生开发:  代码 → 直接编译为机器码 → 运行在 iOS 设备上
Flutter:        Dart 代码 → 编译为 ARM 机器码 → 自绘引擎渲染 UI
React Native:   JS 代码 → Bridge → 调用 iOS 原生组件渲染
维度 Swift 原生 Flutter React Native
语言 Swift Dart JavaScript
UI 渲染 iOS 原生组件 自绘引擎(Skia) 映射到原生组件
编译产物 原生机器码 原生机器码 JS Bundle + 原生壳
平台支持 仅 iOS/macOS iOS + Android + Web + 桌面 iOS + Android
运行性能 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐½ ⭐⭐⭐⭐

5.2 UI 渲染机制的区别

Swift 原生 ------ 直接使用系统组件

objectivec 复制代码
Swift 代码 → 直接调用 iOS UIKit/SwiftUI 组件 → 系统渲染(UILabel, UIView 等)
  • 用的是 Apple 自己的组件,外观、动画、交互 100% 符合 iOS 规范
  • 系统更新组件样式,App 自动跟着变

Flutter ------ 自己画一切

css 复制代码
Dart 代码 → Flutter Framework(Widget 树)→ Skia 渲染引擎 → 直接在 Canvas 上画像素
  • 完全不使用 iOS 原生组件,Flutter 自己用 Skia 画了一个"Text"、一个"Button"
  • iOS 和 Android 上看起来一模一样(都是画出来的)
  • 代价:和系统原生风格有细微差异,系统更新 UI 风格时 Flutter 不会自动跟随

React Native ------ 映射到原生组件

objectivec 复制代码
JSX 代码 → React Native 解析 → Bridge 传递指令 → iOS 端创建真正的 UIView/UILabel → 系统渲染
  • <Text> 在 iOS 上真的创建了一个 UILabel
  • 渲染出来的是真正的 iOS 原生组件,外观和原生一致
  • 代价:JS 和原生之间 Bridge 通信有延迟

5.3 性能对比

场景 Swift Flutter RN
简单页面 极快 极快 快
复杂列表 极快 很快 较快(需优化)
复杂动画 极快 很快 一般
频繁交互 极快 很快 Bridge 可能卡顿

RN 的性能瓶颈(旧架构):

arduino 复制代码
JS 线程                    Bridge(序列化/反序列化)           原生线程
┌──────────┐              ┌──────────────┐              ┌──────────┐
│ JS 逻辑    │ ──JSON消息──→ │   Bridge     │ ──解析消息──→ │ 原生组件  │
│ 虚拟 DOM   │ ←─JSON消息── │  (异步队列)   │ ←─回传结果── │ 渲染执行  │
└──────────┘              └──────────────┘              └──────────┘

问题:每次交互都要跨 Bridge → 序列化 → 反序列化 → 异步等待

RN 新架构(Fabric + TurboModules):

scss 复制代码
JS 线程                     JSI(直接引用)              原生线程
┌──────────┐              ┌──────────────┐              ┌──────────┐
│ JS 逻辑    │ ──C++直接调用─→ │    JSI       │ ──同步调用──→ │ 原生组件  │
│ 虚拟 DOM   │ ←──直接返回─── │ (同步桥接)    │ ←─直接返回─── │ 渲染执行  │
└──────────┘              └──────────────┘              └──────────┘

改进:JSI 允许 JS 直接持有 C++ 对象引用,无需序列化

5.4 开发体验对比

Swift Dart/Flutter JavaScript/RN
学习曲线 中等 低(类似 JS + Java) 低(前端开发者熟悉)
类型系统 强类型,优秀 强类型,优秀 弱类型(TS 可弥补)
生态规模 Apple 生态,丰富 Flutter 生态,够用 npm 最大生态
热重载 ❌ 需重新编译 ✅ 秒级热重载 ✅ 秒级热重载

5.5 平台能力访问

erlang 复制代码
Swift:    100% 能力,直接调用,零成本
Flutter:  90% 能力有现成插件,10% 需自己写原生代码桥接
RN:       90% 能力有现成库,10% 需自己写原生代码桥接

常用能力(相机、定位、推送)→ 三个方案都能轻松搞定
冷门能力(ARKit、HealthKit、HomeKit)→ Swift 直接用,Flutter/RN 要自己写桥接
新出的 iOS API → Swift 立刻能用,Flutter/RN 要等插件或自己实现

5.6 App 体积对比

复制代码
Swift 原生 App:    ~2-5 MB(空项目)
Flutter App:       ~15-20 MB(含 Skia 引擎 + Dart 运行时)
React Native App:  ~8-12 MB(含 JSC/Hermes 引擎 + JS Bundle)

5.7 选型建议

复制代码
选 Swift 原生:
  ✅ 只做 iOS 平台,不需要 Android
  ✅ 深度依赖 iOS 专有功能(ARKit、HealthKit、SiriKit 等)
  ✅ 对性能要求极致(游戏、视频编辑、实时音频处理)
  ✅ 追求最完美的 iOS 体验和系统一致性

选 Flutter:
  ✅ 需要 iOS + Android 双端,且追求高性能
  ✅ UI 复杂、动画多、自定义程度高
  ✅ 未来可能扩展到 Web / 桌面
  ✅ 对 UI 一致性要求高(双端看起来一样)

选 React Native:
  ✅ 需要 iOS + Android 双端
  ✅ 团队已有 React/JS 技术栈
  ✅ 内容展示类 App(电商、社交、资讯)
  ✅ 希望复用 Web 端的 JS 逻辑/状态管理
  ✅ 需要热更新(App Store 不用重新审核)

六、最小启动步骤

6.1 Swift(iOS 原生)

bash 复制代码
# 前置:安装 Xcode(App Store 下载)

# 方式1:命令行创建
mkdir MySwiftApp && cd MySwiftApp
# 用 Xcode 打开:File → New → Project → iOS → App → SwiftUI
open -a Xcode .

# 方式2:命令行直接创建(Xcode 14+)
# 在 Xcode 中:Product → Run(⌘R)

最小 SwiftUI 代码:

swift 复制代码
import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            Text("Hello, iOS!")
        }
    }
}

6.1b Kotlin(Android 原生)

bash 复制代码
# 前置:安装 Android Studio

# 创建项目
# Android Studio → New Project → Empty Activity → Kotlin
# 包名:com.example.myapp
# 最低 SDK:API 24: Android 7.0

最小 Kotlin 代码(MainActivity.kt):

kotlin 复制代码
package com.example.myapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("Hello, Android!")
        }
    }
}

Gradle 依赖(build.gradle.kts):

kotlin 复制代码
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

dependencies {
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.activity:activity-compose:1.8.0")
    implementation(platform("androidx.compose:compose-bom:2024.02.00"))
    implementation("androidx.compose.material3:material3")
}

6.2 Flutter

bash 复制代码
# 前置:安装 Flutter SDK
# https://docs.flutter.dev/get-started/install/macos

# 创建项目
flutter create my_app
cd my_app

# 运行(连接设备或启动模拟器)
flutter run

最小 Flutter 代码(已自动生成在 lib/main.dart):

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
  home: Scaffold(body: Center(child: Text('Hello, Flutter!'))),
));

6.3 React Native

bash 复制代码
# 方式1:Expo(推荐新手,零配置)
npx create-expo-app my_app
cd my_app
npx expo start

# 方式2:React Native CLI(完整原生访问)
npx react-native init MyApp
cd MyApp
npx react-native run-ios

最小 RN 代码(App.tsx):

tsx 复制代码
import { Text, View } from 'react-native';

export default function App() {
  return <View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
    <Text>Hello, RN!</Text>
  </View>;
}

6.4 Ionic

bash 复制代码
# 前置:Node.js >= 16
npm install -g @ionic/cli

# 创建项目(选 Vue/React/Angular)
ionic start myApp tabs --type=vue
cd myApp

# 浏览器预览
ionic serve

# 添加平台并运行
ionic cap add ios
ionic cap run ios

6.5 UniApp

bash 复制代码
# 方式1:CLI 创建(Vue3)
npx degit dcloudio/uni-preset-vue#vite myApp
cd myApp
npm install
npm run dev:h5           # H5 预览
npm run dev:mp-weixin    # 微信小程序预览

# 方式2:HBuilderX(官方 IDE,可视化创建)
# 下载 HBuilderX → 新建项目 → uni-app → 运行

6.6 Taro

bash 复制代码
# 创建项目
npx @tarojs/cli init myApp
cd myApp
npm install

# 运行到不同端
npm run dev:h5           # H5
npm run dev:weapp        # 微信小程序
npm run dev:rn           # React Native

6.7 Cordova

bash 复制代码
# 前置:Node.js + Android SDK / Xcode
npm install -g cordova

# 创建项目
cordova create myApp com.example.myapp MyApp
cd myApp

# 添加平台
cordova platform add ios
cordova platform add android

# 运行
cordova run ios
cordova run android

6.8 H5 套壳(最小实现)

iOS 端(SwiftUI):

swift 复制代码
import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()
        webView.load(URLRequest(url: URL(string: "https://your-h5-site.com")!))
        return webView
    }
    func updateUIView(_ uiView: WKWebView, context: Context) {}
}

@main
struct ShellApp: App {
    var body: some Scene {
        WindowGroup { WebView() }
    }
}

Android 端(Kotlin):

kotlin 复制代码
// MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val webView = WebView(this)
        webView.settings.javaScriptEnabled = true
        webView.loadUrl("https://your-h5-site.com")
        setContentView(webView)
    }
}

七、快速选型速查

css 复制代码
追求性能 → Flutter > React Native > Ionic/Cordova > H5套壳
追求跨端(含小程序)→ UniApp / Taro
追求开发速度(已有H5)→ H5套壳(但功能受限)
需要原生API + 已有H5 → Ionic / Cordova
团队已有React → React Native
团队已有Vue → UniApp
只做 iOS → Swift
只做 Android → Kotlin

八、打包与发布

8.1 各技术打包产物概览

技术 iOS 产物 Android 产物 打包工具
Swift 原生 .ipa --- Xcode
Kotlin 原生 --- .apk / .aab Android Studio / Gradle
Flutter .ipa .apk / .aab flutter build
React Native .ipa .apk / .aab Xcode / Gradle / Expo
Ionic .ipa .apk / .aab ionic cap build / Xcode / Gradle
Cordova .ipa .apk / .aab cordova build / Xcode / Gradle
UniApp .ipa .apk / .aab HBuilderX 云打包 / 本地打包
Taro .ipa(RN端) .apk / .aab(RN端) 依赖 RN 打包流程
H5 套壳 .ipa .apk / .aab 取决于壳的编写方式

APK vs AAB:Google Play 自 2021 年 8 月起要求新应用必须使用 AAB(Android App Bundle)格式上传,AAB 会根据用户设备动态分发所需资源,体积更小。APK 仍可用于侧载或国内应用市场。


8.2 iOS 打包流程(所有技术通用)

前置条件
markdown 复制代码
1. Apple Developer 账号($99/年,个人或公司)
2. Mac 电脑(Xcode 仅限 macOS)
3. 真机设备(用于测试,模拟器无法测试推送、相机等)
完整流程
bash 复制代码
# Step 1: 申请 Apple Developer 账号
# https://developer.apple.com → 注册 → 支付 $99/年

# Step 2: 创建证书和描述文件(Xcode 自动管理或手动)
# 方式A:Xcode 自动签名(推荐新手)
# Xcode → Target → Signing & Capabilities → Team → 选择你的 Apple ID
# 勾选 "Automatically manage signing"

# 方式B:手动管理(企业/多人协作)
# Apple Developer Portal → Certificates → 创建 Distribution 证书
# → Identifiers → 创建 App ID(Bundle ID 如 com.example.myapp)
# → Profiles → 创建 Ad Hoc / App Store 描述文件

# Step 3: 配置应用信息
# Info.plist:应用名称、Bundle ID、权限描述(相机、定位等)
# Assets.xcassets:App Icon(1024x1024)、Launch Screen

# Step 4: 构建 Release 版本
# Xcode → Product → Scheme → Edit Scheme → Run → Build Configuration → Release
# Product → Archive(⌘+Shift+U)

# Step 5: 导出或上传
# Organizer(Window → Organizer)→ 选择 Archive → Distribute App
# → App Store Connect → Upload 或 Export

# Step 6: App Store Connect 提交
# https://appstoreconnect.apple.com
# → 我的 App → 新建 App → 填写元数据(名称、描述、截图、关键词)
# → 选择构建版本 → 提交审核
# 审核时间:通常 1-3 个工作日
各技术的 iOS 打包命令
bash 复制代码
# Flutter
flutter build ios --release
# 然后 Xcode → Product → Archive

# React Native(CLI)
cd ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release archive

# React Native(Expo)
npx expo prebuild
npx expo run:ios --configuration Release
# 或 EAS Build(云端打包)
npx eas build --platform ios

# Ionic
cd ios && xcodebuild -workspace App.xcworkspace -scheme App -configuration Release archive

# Cordova
cordova build ios --release --device
# 然后 Xcode → Product → Archive

# UniApp
# HBuilderX → 发行 → 原生 App-云打包 → 选择 iOS 证书 → 打包

8.3 Android 打包流程(所有技术通用)

前置条件
markdown 复制代码
1. Android Studio
2. JDK 17+
3. 签名密钥(Release 版本必须)
完整流程
bash 复制代码
# Step 1: 生成签名密钥(只需做一次,妥善保管)
keytool -genkey -v \
  -keystore my-release-key.jks \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -alias my-alias

# 会要求输入:
# - 密钥库密码
# - 密钥密码(可与库密码相同)
# - 姓名、组织、城市等信息

# Step 2: 配置签名(各技术配置位置不同,原理相同)

Gradle 签名配置(android/app/build.gradle 或 android/build.gradle):

gradle 复制代码
android {
    signingConfigs {
        release {
            storeFile file("my-release-key.jks")
            storePassword "your-store-password"
            keyAlias "my-alias"
            keyPassword "your-key-password"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled true      // 代码混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

生产环境不要把密码写死在代码里,使用环境变量或 local.properties:

properties 复制代码
# local.properties(不提交到 Git)
STORE_FILE=my-release-key.jks
STORE_PASSWORD=your-password
KEY_ALIAS=my-alias
KEY_PASSWORD=your-password
gradle 复制代码
// build.gradle 中读取
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

signingConfigs {
    release {
        storeFile file(properties.getProperty('STORE_FILE'))
        storePassword properties.getProperty('STORE_PASSWORD')
        keyAlias properties.getProperty('KEY_ALIAS')
        keyPassword properties.getProperty('KEY_PASSWORD')
    }
}
bash 复制代码
# Step 3: 构建 Release

# APK(国内应用市场、侧载)
./gradlew assembleRelease
# 产物:android/app/build/outputs/apk/release/app-release.apk

# AAB(Google Play 必需)
./gradlew bundleRelease
# 产物:android/app/build/outputs/bundle/release/app-release.aab

# Step 4: 上传应用市场
# Google Play Console: https://play.google.com/console
# 国内:华为、小米、OPPO、vivo、应用宝等各自开发者后台
各技术的 Android 打包命令
bash 复制代码
# Flutter
flutter build apk --release              # APK
flutter build appbundle --release        # AAB

# React Native(CLI)
cd android && ./gradlew assembleRelease   # APK
cd android && ./gradlew bundleRelease     # AAB

# React Native(Expo)
npx eas build --platform android          # EAS 云端打包

# Ionic
cd android && ./gradlew assembleRelease

# Cordova
cordova build android --release

# UniApp
# HBuilderX → 发行 → 原生 App-云打包 → 选择 Android 证书 → 打包

8.4 小程序打包(UniApp / Taro)

bash 复制代码
# UniApp
npm run build:mp-weixin    # 编译到微信小程序
# 然后用微信开发者工具 → 导入 dist/build/mp-weixin → 上传

# Taro
npm run build:weapp        # 编译到微信小程序
# 同样用微信开发者工具上传

# 微信小程序发布流程:
# 1. 微信开发者工具 → 上传(填写版本号)
# 2. 微信公众平台 → 版本管理 → 提交审核
# 3. 审核通过 → 发布

8.5 签名与证书管理

平台 证书类型 有效期 丢失后果
iOS Distribution Certificate 1 年 需重新生成,不影响已上架 App
iOS Provisioning Profile 1 年 需重新生成,不影响已上架 App
Android Keystore (.jks) 25 年+ 永久丢失无法更新 App

Android 的 Keystore 一旦丢失,永远无法用相同包名发布更新,Google Play 和国内市场都要求相同的签名。务必备份到安全位置。


九、热更新方案

9.1 什么是热更新?

热更新 = 不经过应用商店审核,直接下发代码/资源更新到用户设备。

复制代码
传统更新:发现 Bug → 修复 → 打包 → 提交审核 → 等待 1-3 天 → 用户下载更新
热更新:   发现 Bug → 修复 → 上传补丁 → 秒级生效 → 用户下次打开自动更新

9.2 各技术支持情况

技术 热更新支持 方案 限制
Swift 原生 ❌ 不支持 --- Apple 禁止热更新原生代码
Kotlin 原生 ❌ 不支持 --- Google 限制较少,但原生代码热更新也不推荐
Flutter ⚠️ 有限支持 shorebird、flutter_code_push 社区方案,非官方
React Native ✅ 支持 CodePush、Expo Updates JS Bundle 可热更新,原生模块不行
Ionic / Cordova ✅ 支持 CodePush、自定义实现 Web 资源可热更新
UniApp ✅ 支持 DCloud 云打包热更新 官方支持,WGT 资源包更新
Taro ⚠️ 有限支持 依赖 RN 端的热更新能力 H5/小程序端天然支持(就是网页)

9.3 React Native 热更新(CodePush)

bash 复制代码
# 安装 App Center CLI
npm install -g appcenter-cli

# 登录
appcenter login

# 发布更新
appcenter codepush release-react -a MyOrg/MyApp -d Production
javascript 复制代码
// App.js 中集成
import codePush from 'react-native-code-push';

function App() {
  // ...
}

export default codePush({
  checkFrequency: codePush.CheckFrequency.ON_APP_RESUME
})(App);

9.4 UniApp 热更新

bash 复制代码
# HBuilderX → 发行 → 制作应用 wgt 包
# 将 wgt 包上传到服务器

# App 中检查更新
uni.request({
  url: 'https://your-server.com/check-update',
  success: (res) => {
    if (res.data.hasUpdate) {
      uni.downloadFile({
        url: res.data.wgtUrl,
        success: (downloadRes) => {
          uni.installUpdate({
            filePath: downloadRes.tempFilePath
          });
        }
      });
    }
  }
});

9.5 Apple 对热更新的限制

arduino 复制代码
Apple App Store 审核指南 2.5.2:
"App 不得下载或安装可执行代码"

允许:
  ✅ JS 脚本解释执行(RN、WebView 内的 JS)
  ✅ 资源文件更新(图片、配置)
  ✅ 使用 Apple 的 JavaScriptCore 框架

禁止:
  ❌ 下载并执行原生机器码
  ❌ 使用 dlopen、dlsym 等动态加载
  ❌ 绕过审核机制更新核心功能

十、调试方式

10.1 各技术调试工具

技术 调试工具 断点调试 UI 检查 性能分析
Swift Xcode ✅ LLDB ✅ View Debugger ✅ Instruments
Kotlin Android Studio ✅ ✅ Layout Inspector ✅ Profiler
Flutter Flutter DevTools ✅ ✅ Widget Inspector ✅ Performance
React Native Chrome DevTools / Flipper ✅ ✅ Element Inspector ✅ Hermes Profiler
Ionic Chrome DevTools ✅ ✅ ❌(依赖浏览器工具)
UniApp HBuilderX / 微信开发者工具 ❌ ✅ ❌
Taro 微信开发者工具 / Chrome ❌ ✅ ❌

10.2 真机调试

bash 复制代码
# iOS 真机调试
# 1. 用数据线连接 iPhone
# 2. Xcode → Window → Devices and Simulators → 信任设备
# 3. 选择真机 → Run(⌘R)
# 4. 设置 → 隐私与安全性 → 开发者模式(iOS 16+)

# Android 真机调试
# 1. 开启开发者选项:设置 → 关于手机 → 连点版本号 7 次
# 2. 开启 USB 调试
# 3. adb devices 确认连接
# 4. Android Studio 或命令行运行

10.3 日志查看

bash 复制代码
# iOS 日志
# Xcode → Window → Devices and Simulators → 选择设备 → Open Console
# 或命令行:
idevicesyslog | grep MyApp

# Android 日志
adb logcat -s "MyApp:D"    # 过滤特定 Tag
adb logcat | grep flutter   # Flutter 日志
adb logcat | grep ReactNativeJS  # RN 日志

十一、鸿蒙 HarmonyOS(补充)

11.1 鸿蒙开发技术

技术 说明 适用场景
ArkTS(原生) 鸿蒙官方语言,TypeScript 超集 追求最佳性能和体验
ArkUI(声明式 UI) 类似 SwiftUI / Flutter 的声明式语法 鸿蒙原生 App
元服务(Atomic Service) 免安装、卡片化 轻量服务
跨平台框架适配 Flutter、RN 已有鸿蒙适配版本 已有跨平台项目迁移

11.2 最小启动步骤(ArkTS)

bash 复制代码
# 前置:安装 DevEco Studio(鸿蒙官方 IDE)
# https://developer.harmonyos.com

# 创建项目
# DevEco Studio → Create Project → Empty Ability → ArkTS

最小 ArkTS 代码(Index.ets):

typescript 复制代码
@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('Hello, HarmonyOS!')
        .fontSize(24)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

11.3 鸿蒙打包

bash 复制代码
# DevEco Studio → Build → Build Hap(s)/App(s)
# 产物:.hap(HarmonyOS Package)
# 发布:华为 AppGallery Connect
相关推荐
2501_915918411 天前
Windows 上开发 React Native iOS,真机调试、Fast Refresh 与打包 ipa
windows·vscode·react native·ios·个人开发·swift·敏捷流程
2501_948122632 天前
Qs 跨端三方库仓颉适配全流程
python·react native·django·tornado
tech_zjf5 天前
下班后,我做了一个把照片贴进日历的 iPhone 应用:Daypatch
react native·app·产品
结局无敌10 天前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
结局无敌10 天前
React Native for OpenHarmony 实战:三方库 react-native-paper 的鸿蒙化适配指南
javascript·人工智能·深度学习·react native·react.js·ecmascript·harmonyos
结局无敌10 天前
React Native for OpenHarmony 实战:三方库 react-native-progress-steps 的鸿蒙化适配指南
javascript·人工智能·深度学习·react native·react.js·harmonyos
donk131412 天前
React Native for OpenHarmony 实战:三方库 react-native-circular-action-menu 的鸿蒙化适配指南
javascript·分布式·react native·react.js·wpf·harmonyos
donk131413 天前
React Native for OpenHarmony 实战:三方库 react-native-step-indicator 的鸿蒙化适配指南
分布式·react native·react.js·wpf·harmonyos
donk131413 天前
React Native for OpenHarmony 实战:三方库 react-native-segmented-control-tab 的鸿蒙化适配指南
javascript·react native·react.js·华为·harmonyos
donk131413 天前
React Native for OpenHarmony 实战:三方库 react-native-toast-message 的鸿蒙化适配指南
react native·react.js·音视频·harmonyos