移动端原生框架对比评测

移动端开发技术知识库

一、技术分类总览

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

阵营 代表技术 渲染方式 性能
自绘引擎 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
相关推荐
传奇开心果编程12 小时前
【声明式UI开发实用技术学与练】第8课 状态提升与下放
学习·flutter·react native·ui·swiftui·composer
传奇开心果编程1 天前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程2 天前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
500842 天前
React Native for OpenHarmony 实战:三方库 react-native-url-polyfill 的鸿蒙化适配指南
javascript·react native·react.js·性能优化·electron·harmonyos
传奇开心果编程2 天前
【现代声明式UI学与练】第9课 性能优化——渲染优化、列表优化、内存优化、启动优化
学习·flutter·react native·ui·性能优化·swiftui·android jetpack
500843 天前
React Native for OpenHarmony 实战:三方库 react-native-volume-control 的鸿蒙化适配指南
javascript·react native·react.js·electron·harmonyos
500847 天前
React Native for OpenHarmony 实战:三方库 react-native-crypto-js 的鸿蒙化适配指南
javascript·react native·性能优化·electron·harmonyos
500847 天前
React Native for OpenHarmony 实战:三方库 react-native-device-name 的鸿蒙化适配指南
深度学习·react native·react.js·机器学习·harmonyos
500848 天前
React Native for OpenHarmony 实战:三方库 react-native-torch 的鸿蒙化适配指南
javascript·react native·react.js·harmonyos