Flutter 打包APP (Android IOS)

article/2025/9/19 11:23:08

打包Android apk

参考
https://flutter.dev/docs/deployment/android
https://flutterchina.club/android-release/
Flutter项目打包成安卓apk详解来了(解决安装没网络问题)
【Flutter 专题】39 图解 iOS 打包 IPA 文件
Flutter - 打包APK、IPA 及 IOS上传APPLE Store详解
Flutter-Apk 大小优化探索
Flutter apk最简单的瘦身方式

检查AndroidManifest.xml

  1. 修改app名字
  2. 修改包名
  3. 配置权限(解决apk安装后无网络)

注意,main 和 profile 目录下的Manifest文件都要检查
这两个 main & profile 目录下的Manifest文件都要添加权限
在这里插入图片描述

main & profile 目录下的Manifest文件都添加权限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

main.dart

在这里插入图片描述

build.gradle (app目录)

  1. application id
  2. version code & version name(在 local.properties统一定义)
  3. minSdk & targetSdk

versionCode和versionName 在 local.properties统一定义

修改启动图标

小工具: 一键生成所有尺寸的应用图标/启动图,同时生成 iOS、Android 和 PhoneGap 应用的图标。遵循 Apple、 Google 官方标准
https://icon.wuruihong.com/

把logo上传到上述网站中,就能导出Android 和 iOS的启动图标了,直接复制到对应的目录替换即可。

APP签名

1. 创建 keystore

如果没有,请通过在运行以下命令来创建一个:

keytool -genkey -v -keystore ~/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key

或者参考以下命令:

keytool -genkey -v -keystore 自定义.keystore -alias 自定义别名 -keyalg RSA -keysize 2048 -validity 10000 -storepass 自定义密码 -keypass 自定义密码

如用第一个命令,创建的目录会在/Users/your_user_name/key.jks,移动到flutter项目的Android目录下

2. 引用应用程序中的keystore

创建一个名为< app dir >/android/key.properties的文件,其中包含对密钥库的引用:

storePassword=<password from previous step>
keyPassword=<password from previous step>
keyAlias=key
storeFile=<location of the key store file, e.g.  ../key.jks>
3. 配置app build.gradle - 在gradle中配置签名

1.替换:

android {

def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))android {

2.替换:

buildTypes {release {// TODO: Add your own signing config for the release build.// Signing with the debug keys for now, so `flutter run --release` works.signingConfig signingConfigs.debug}
}

为:

signingConfigs {release {keyAlias keystoreProperties['keyAlias']keyPassword keystoreProperties['keyPassword']storeFile file(keystoreProperties['storeFile'])storePassword keystoreProperties['storePassword']}
}
buildTypes {release {signingConfig signingConfigs.release//signingConfig signingConfigs.debug}
}

[可选] 开启混淆

  • 对apk的代码安全和包大小有要求
  • 确保使用的第三方库不被混淆

默认情况下 flutter 不会开启 Android 的混淆。

如果使用了第三方 Java 或 Android 库,也许你想减小 apk 文件的大小或者防止代码被逆向破解。

  1. 配置混淆
    创建 /android/app/proguard-rules.pro 文件,并添加以下规则:
    !!! 注意, 是app目录下的
#如果使用了第三方 Java 或 Android 库 也需要添加与之对应的规则#Flutter Wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.**  { *; }
-keep class io.flutter.util.**  { *; }
-keep class io.flutter.view.**  { *; }
-keep class io.flutter.**  { *; }
-keep class io.flutter.plugins.**  { *; }
  1. 启用 混淆/压缩
    打开 /android/app/build.gradle 文件,定位到 buildTypes 块。
    release 配置中将 minifyEnableduseProguard 设为 true,再将混淆文件指向上一步创建的文件。
android {...buildTypes {release {signingConfig signingConfigs.releaseminifyEnabled trueuseProguard trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}

到此,app打包的准备工作已经完成

构建一个发布版(release)APK

使用命令行:

  1. cd flutter工程根目录
  2. 运行flutter build apk (flutter build 默认会包含 --release选项).

打包好的发布APK位于< app dir >/build/app/outputs/apk/app-release.apk。


flutter build apk 的一些细节

  • 对apk进行解压,可以看到flutter默认打包的flutter so库架构为 armeabi-v7a
    在这里插入图片描述
  • 分架构打包,可以减少apk体积
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi

最后的 --split-per-abi 则表示告知需要按照我们指定的类型分别打包(会得到多个apk,每个apk对应一个架构),如果移除则直接构建包含所有 CPU 架构的 Apk 包


打包IOS (待更新…)

在打包前,需要已经申请了Apple的开发者账号

在AppleStore Connect 注册APP&注册APP bundle ID

https://flutter.cn/docs/deployment/ios

ios打包过程遇到的问题

执行flutter build ios

error: The linked framework 'Pods_Runner.framework' is missing one or more architectures required by this target: armv7. (in target 'Runner' from project 'Runner')

在这里插入图片描述
在XCode中,Runner下的Build Settings标签中,找到 architectures - ExcludedArchitectures
为Release和Profile添加如上图4/5所示的架构


执行flutter build ios

Xcode build done.                                           41.3s
Failed to build iOS app
Error output from Xcode build:
↳** BUILD FAILED **Xcode's output:
↳/Users/keihong/.pub-cache/hosted/pub.flutter-io.cn/flutter_webview_plugin-0.4.0/ios/Classes/FlutterWebviewPlugin.m:92:22: warning: incompatible pointer to integer conversion assigning to 'BOOL' (aka 'signed char') from 'id_Nullable' [-Wint-conversion]_enableAppScheme = call.arguments[@"enableAppScheme"];^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/Users/keihong/.pub-cache/hosted/pub.flutter-io.cn/flutter_webview_plugin-0.4.0/ios/Classes/FlutterWebviewPlugin.m:434:98: warning: values of type 'NSInteger' should not be used as format arguments; add an explicit cast to'long' instead [-Wformat][channel invokeMethod:@"onHttpError" arguments:@{@"code": [NSString stringWithFormat:@"%ld", error.code], @"url": url}];~~~   ^~~~~~~~~~%ld   (long)/Users/keihong/.pub-cache/hosted/pub.flutter-io.cn/flutter_webview_plugin-0.4.0/ios/Classes/FlutterWebviewPlugin.m:442:98: warning: values of type 'NSInteger' should not be used as format arguments; add an explicit cast to'long' instead [-Wformat][channel invokeMethod:@"onHttpError" arguments:@{@"code": [NSString stringWithFormat:@"%ld", error.code], @"error": error.localizedDescription}];~~~   ^~~~~~~~~~%ld   (long)/Users/keihong/.pub-cache/hosted/pub.flutter-io.cn/flutter_webview_plugin-0.4.0/ios/Classes/FlutterWebviewPlugin.m:450:106: warning: values of type 'NSInteger' should not be used as format arguments; add an explicit cast to'long' instead [-Wformat][channel invokeMethod:@"onHttpError" arguments:@{@"code": [NSString stringWithFormat:@"%ld", response.statusCode], @"url": webView.URL.absoluteString}];~~~   ^~~~~~~~~~~~~~~~~~~%ld   (long)4 warnings generated.../../../../../../../.pub-cache/hosted/pub.flutter-io.cn/flutter_color_plugin-1.0.0/lib/flutter_color_plugin.dart:35:35: Warning: Operand of null-aware operation '!' has type 'String' which excludes null.int? color = sColorNameMap[(colorString!.toLowerCase())];^Command PhaseScriptExecution failed with a nonzero exit codenote: Using new build systemnote: Building targets in parallelnote: Planning buildnote: Analyzing workspacenote: Constructing build descriptionnote: Build preparation completewarning: None of the architectures in ARCHS (arm64, armv7) are valid. Consider setting ARCHS to $(ARCHS_STANDARD) or updating it to include at least one value from VALID_ARCHS (arm64, arm64e, armv7, armv7s) which is not inEXCLUDED_ARCHS (arm64, armv7). (in target 'Runner' from project 'Runner')Encountered error while building for device.

我这样解决了 flutter_webview_plugin的报错:
https://github.com/Baseflow/flutter-permission-handler/issues/191#issuecomment-575022497

flutter clean
flutter build ios

Xcode build done.                                           36.7s
Failed to build iOS app
Error output from Xcode build:
↳** BUILD FAILED **Xcode's output:
↳4 warnings generated.../../../../../../../.pub-cache/hosted/pub.flutter-io.cn/flutter_color_plugin-1.0.0/lib/flutter_color_plugin.dart:35:35: Warning: Operand of null-aware operation '!' has type 'String' which excludes null.int? color = sColorNameMap[(colorString!.toLowerCase())];^Command PhaseScriptExecution failed with a nonzero exit codenote: Using new build systemnote: Building targets in parallelnote: Planning buildnote: Analyzing workspacenote: Constructing build descriptionnote: Build preparation completewarning: None of the architectures in ARCHS (arm64, armv7) are valid. Consider setting ARCHS to $(ARCHS_STANDARD) or updating it to include at least one value from VALID_ARCHS (arm64, arm64e, armv7, armv7s) which is not inEXCLUDED_ARCHS (arm64, armv7). (in target 'Runner' from project 'Runner')Encountered error while building for device.

解决方法:flutter_color_plugin 的错误,自己写一个ColorUtil…


Failed to build iOS app
Error output from Xcode build:
↳** BUILD FAILED **Xcode's output:
↳Command PhaseScriptExecution failed with a nonzero exit codenote: Using new build systemnote: Building targets in parallelnote: Planning buildnote: Analyzing workspacenote: Constructing build descriptionnote: Build preparation completewarning: None of the architectures in ARCHS (arm64, armv7) are valid. Consider setting ARCHS to $(ARCHS_STANDARD) or updating it to include at least one value from VALID_ARCHS (arm64, arm64e, armv7, armv7s) which is not inEXCLUDED_ARCHS (arm64, armv7). (in target 'Runner' from project 'Runner')Encountered error while building for device.

改成下图所示内容后,出现了另一个错误:
在这里插入图片描述

error: The linked framework 'Pods_Runner.framework' is missing one or more architectures required by this target: armv7s. (in target 'Runner' from project 'Runner')

参考:https://www.jianshu.com/p/5af69bb58916

我的解决:删除ios目录,然后重建ios项目…

flutter create -i swift .

IOS打包步骤记录

  1. flutter build ios
  2. 打开xcode,修改版本号
  3. Project - archive
  4. Distribute app
  5. 根据实际需要选择 Ad-Hoc等
  6. 取消rebuild from bitcode

http://chatgpt.dhexx.cn/article/F4dpjq9Q.shtml

相关文章

【uniapp小程序】—— APP项目云打包(安卓)

&#x1f341; 前言 之前小程序系列文章写了配置页面和封装自定义组件&#xff0c;这次写一下开发完成我们的项目后&#xff0c;如何进行打包安装。 本文主要讲述的是使用 uniapp打包安卓。 &#x1f342; 正文 第一步&#xff1a;查看自己的项目的基础配置 第二步&#xff1a…

前端打包利器,webpack工具,app打包工具

什么是 webpack&#xff1f; webpack是近期最火的一款模块加载器兼打包工具&#xff0c;它能把各种资源&#xff0c;例如JS&#xff08;含JSX&#xff09;、coffee、样式&#xff08;含less/sass&#xff09;、图片等都作为模块来使用和处理。 我们可以直接使用 require(XXX) 的…

app打包流程

在项目根目录 npm run build 会多出一个dist文件 打开hubuildX 文件–》新建 —》项目 5app—》模板默认模板–》创建 --》 项目根目录右键 --》在外部资源打开 --》找到刚才打包的dist文件里的所有文件到这个新建的项目里面 —》 全部替换 --》 把css image js 文件夹删…

干货,快速的教你如何打包app

所需工具&#xff1a;HbuilderX hbuilderX下载地址&#xff0c;下载符合自己电脑的就行。 1.新建项目 步骤&#xff1a;文件 → 新建 → 项目 2.选择5app,输入项目名称&#xff0c;选择项目存放目录 3.和我们正常的项目一样&#xff0c;只不过多了 unpackage 和 manifest.j…

HTML一键打包APK工具(安卓应用APP)

工具简介 “HMTL一键打包APK工具”可以把本地HTML项目或者网站打包为一个安卓应用APK文件&#xff0c;无需编写任何代码&#xff0c;支持在安卓设备上安装运行。 打包工具群&#xff1a;429338543 下载地址&#xff1a; 点击进入下载页面 加群获取最新软件 软件交流群&#…

【 uniapp 】打包Android的apk(原生APP-云打包),及发布测试

前言&#xff1a; 跨端(小程序、Android、IOS)项目开发好了&#xff0c;我们如何去利用 uniapp 的云打包去打包 apk 文件&#xff0c;然后上传测试呢&#xff1f;今天我们一起来学习一下&#xff0c;一步一步如何实现&#xff01; 目录 一、 打包 Android &#xff0c;生成apk…

一款好用的应用程序打包工具

工具简介 Inno Setup用Delphi写成&#xff0c;其官方网站同时也提供源程序免费下载。Inno Setup是一个免费的安装制作软件&#xff0c;小巧、简便、精美是其最大特点&#xff0c;支持pascal脚本&#xff0c;能快速制作出标准Windows2000风格的安装界面&#xff0c;足以完成一般…

快速打包、发布和管理应用——AppUploader工具介绍

AppUploader的主要功能介绍 购买激活码 在AppUploader官网上&#xff0c;可以购买激活码激活账号&#xff0c;根据需求购买&#xff0c;单次购买多个比单次购买单个更划算。 激活激活码 购买激活码后&#xff0c;可以在激活页面输入订单进行查询激活码&#xff0c;从而激活账…

【推荐】App多渠道打包工具

Android应用市场存在大大小小几百个商店&#xff08;一个商店就代表一个渠道&#xff0c;比如&#xff1a;360手机助手、小米应用市场、华为应用市场、三星应用市场&#xff09;&#xff0c;每当App需要发布新版本时&#xff0c;我们就需要重新分发一遍每一个应用市场&#xff…

Android多渠道打包的几种常用工具

Android项目开发完&#xff0c;多渠道打包是必不可少的环节。其原理在于&#xff0c;通过在Android安卓包中添加不同的标识&#xff0c;区分各个渠道下载来源&#xff0c;用于统计App在不同应用市场或渠道合作中的各项数据。 工欲善其事&#xff0c;必先利其器。当在项目中遇到…

在thinkphp中引入自定义的敏感词库

本文主要讲述&#xff0c;如何在thinkphp项目中创建敏感词库方法&#xff0c;如何引入敏感词库&#xff0c;以及如何将敏感词库用到项目中。 首先是在项目的thinkphp的第三方插件目录中&#xff0c;引入自定义的敏感词库。具体的配置路径是 /ThinkPHP/Extend/Library/ORG/Sens…

lua 文件读写处理(操作敏感词库)

最近需要给游戏做一个敏感词新系统&#xff0c;我采用的方法是比较常用的DFA&#xff08;确定有穷状态机&#xff09;算 法&#xff0c;先不讲算法&#xff0c;而这种算法的实现需要一个相应的敏感词库。 我拿到了词库后发现词库中大概有8000个词&#xff0c;其中包括很多重复的…

小怡同学被骂到清空社交平台?各大平台连敏感词库都没有的吗?

敏感词都没有的平台 最近某加拿大籍贯的 rapper 被曝私生活不检点&#xff0c;且极有可能涉及诱X未成-年少-女&#xff0c;成为一个 raper。 当然至于是否属实&#xff0c;其实一个人是否是海王&#xff0c;微信、QQ 聊天记录里面记得清清楚楚。再上升到刑事案件的时候&#x…

敏感关键词 词库_关键词优化难度分析怎么做?老鸟如何一键筛选优质关键词(悬赏1元)...

关键词优化是SEO工作的重点之一&#xff0c;之前聊了关键词挖掘&#xff0c;就有朋友问如何做关键词优化难度的分析&#xff0c;所以决定把这块详细写一写。 同时也说一下我自己的一个关键词优化性价比算法&#xff0c;目前这个算法已经帮我筛选出大量竞争低、流量高的关键词&a…

谷歌归期未定,但敏感词库已经建起来了

西雅图IT圈&#xff1a;seattleit 【今日作者】 PowerBall选号机 身体和灵魂总有一个要 走在买PowerBall的路上 谷歌回归 中国大陆的消息年年有&#xff0c;次次说的有鼻子有眼&#xff0c;而这回好像比哪一次都更靠谱。 从上周开始&#xff0c;谷歌回国的消息就又沸沸扬扬的传…

Python敏感词过滤DFA算法+免费附带敏感词库

DFA简介参考&#xff1a;https://blog.csdn.net/chenssy/article/details/26961957 此篇是上述JAVA敏感词过滤的python版本&#xff0c;完整版本&#xff0c;修改版本 首先我们看看最终处理效果 实例1&#xff1a; 输入字符串 处理结果 核心代码&#xff1a; SensitiveFilt…

Java实现自定义敏感词库过滤

最近接到一个需求&#xff0c;要添加一个敏感词管理模块&#xff0c;一如既往的CURD&#xff0c;敏感词我们添加到了自己的库里。然后进行一个自定义敏感词过滤&#xff0c;话不多说直接贴代码 1、工具类 这里只是最简单的得到敏感词进行转换&#xff0c;可以根据自己的业务需…

node实现敏感词过滤及敏感词库

核心代码 import * as fs from fs; import * as path from path; import * as readline from readline;export default class BadWords {private static _instance: BadWords;private data: Array<string> [];constructor () {const files fs.readdirSync(path.resol…

百度内容审查做敏感词库筛选

最近在做项目的敏感词库筛选更新。笔者最终的目标是通过百度API将现有的敏感词库筛选更新成。 一、准备工作 读者需在百度智能云登陆账号&#xff0c;然后开通百度内容审核功能&#xff0c;然后根据API Key和Secret Key可以获得调用接口所需的access_token。 二、代码调用API…

敏感词过滤之——自定义构建查询词库与快速查询实现

关于敏感词过滤的一点思考与实践 业务场景思考与研究逻辑分析代码实现(php)构建敏感词树分割字符串敏感词树长分支的递归实现读取敏感词库 敏感词树的查询查询实现调用 测试、分析与总结 业务场景 最近在公司维护的小程序上&#xff0c;遇到一个需要用到敏感词过滤功能的业务模…