Flutter 打包APP (Android IOS)
打包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
- 修改app名字
- 修改包名
- 配置权限(解决apk安装后无网络)
注意,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目录)
- application id
- version code & version name(在 local.properties统一定义)
- minSdk & targetSdk
修改启动图标
小工具: 一键生成所有尺寸的应用图标/启动图,同时生成 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 文件的大小或者防止代码被逆向破解。
- 配置混淆
创建 /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.** { *; }
- 启用 混淆/压缩
打开/android/app/build.gradle
文件,定位到buildTypes
块。
在release
配置中将minifyEnabled
和useProguard
设为true
,再将混淆文件指向上一步创建的文件。
android {...buildTypes {release {signingConfig signingConfigs.releaseminifyEnabled trueuseProguard trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}
到此,app打包的准备工作已经完成
构建一个发布版(release)APK
使用命令行:
cd flutter工程根目录
- 运行
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打包步骤记录
- flutter build ios
- 打开xcode,修改版本号
- Project - archive
- Distribute app
- 根据实际需要选择 Ad-Hoc等
- 取消rebuild from bitcode
Flutter 打包APP (Android IOS)相关推荐
- 微信内置浏览器无法下载app(Android/ios)软件 微信内下载链接打不开的解决方法
很多朋友的APP推广链接需要在微信中进行的网页宣传.传播.下载等等,但是各位朋友一定发现了微信中是屏蔽掉了APP的下载链接的.但是微信最为一个最大的社交平台,为了自身的利益,屏蔽掉了所有APK的下载链 ...
- Adobe源码泄漏?3行代码搞定,Flash动画无缝导入Android/iOS/cocos2dx(一)
[注] iOS代码已重构,效率提升90%,200层动画不卡.[2016.10.27] 项目介绍 项目名称:FlashAnimationToMobile 源码. 使用方法点这里. 这是一个把flash中 ...
- uniapp 打包app 引入高德地图sdk
uniapp 打包app 引入高德地图sdk 1. 注册高德地图开放平台账号并添加应用,在应用中添加key 2. 生成自有证书(windows系统) 3. 高德地图key生成 并配置到项目中 4. 地 ...
- flutter ios打包_Flutter通过BasicMessageChannel与Android iOS 的双向通信
更多文章请查看 flutter从入门 到精通 本文章中的完整代码在这里 题记:不到最后时刻,千万别轻言放弃,无论结局成功与否,只要你拼博过,尽力过,一切问心无愧. 通过 Flutter 来进行移动应用 ...
- flutter ios打包_使用 Travis CI 为 Flutter 项目打包 Android/iOS 应用
Travis CI 构建 Building Flutter APKs and IPAs on Travis 这篇文章详细介绍了如何在 Travis CI 上为 Flutter 项目打包 Android ...
- android 启动白屏_从细节入手改善用户体验,Flutter跨平台App开发中设置Android和iOS的启动页
前言 flutter开发App方便快捷,就是冷启动的时候要加载dart引擎有短暂的白屏,严重影响用户体验,这个时候我们就需要设置一个启动图片,想国内大部分App那样(例如微信那个地球),启动App的时 ...
- Flutter设置App的应用名字和应用logo图标的方法(android ios web)
在前面的几期给大家介绍了flutter的安装以及一些简单的配置,还运行了helloword 那么接下来就带领大家了解如何设置应用名称以及图标 Flutter设置App的应用名字和应用logo图标的方法 ...
- 第 3-5 课:Flutter 调试及 Android 和 iOS 打包
在使用不同的开发语言进行开发时,一般都会用到调试.断点调试功能.例如 Web.Android 等等都是支持调试和断点调试的,Flutter 也不例外,支持调试和单元测试功能,还有性能.布局分析器等等. ...
- Flutter 电影 app 应用,兼容 Android 和 iOS,使用豆瓣开放Api。
本着开源精神,将自己独立完成的 Flutter 电影应用开源.项目利用豆瓣现有的 Api,打造了一个完整的电影展示 App.(部分 UI 仿豆瓣电影). 项目是我的本科毕业设计,算不上完美,但也有那么 ...
最新文章
- 数据结构与算法(C++)– 队列(Queue)
- IO多路转接之poll
- arcgis导入excel数据_ArcGIS批量导入数据
- TCP/IP 协议簇的逐层封装
- 消息队列mysql redis那个好_Redis与RabbitMQ作为消息队列的比较
- 用sqlalchemy对mysql数据库增删改查demo
- 计算机网络——物理层设备
- BZOJ 2286 消耗战 (虚树+树形DP)
- java登陆session用法_Java web 登录 使用shiro和基于session的方式有何不同?
- 什么是 ARM 架构处理器?
- 下班前网上搜集的方法哈哈
- python之matplotlib中plt.show()不显示
- 品牌怎么做知乎营销?
- UE4 创建编辑器模块
- [转载]什么是ESD,什么是latch up
- 2021.09青少年软件编程(Python)等级考试试卷(五级)
- 丙烯酸酯PEG丙烯酸酯,DA-PEG-DA
- ip地址计算器php源码,php版 子网掩码计算器
- 找高清视频素材,就上这6个网站。
- springboot+Vue饭店点菜点餐管理系统
热门文章
- linux 脚本 “=~” 表达 意思
- @import 后面的波浪号~ 代表什么意思
- 快速开发框架源码 JNPF 旗舰版 单体版 java+.net6 炎黄盈动
- 使用nexus-3.10x以上版本构建maven私服仓库
- excel取消密码_不让别人修改你的Excel表,只有1%的人用这个最简方法
- mysql returning_Postgres用returning实现mysql的last_insert_id
- 学习streamlit-2
- 利用 HBuilderX 制作新闻列表页以及制作注册页面
- 转发 ---- 2018年阿里巴巴重要开源项目汇总(持续更新中)
- 多中间层的层次分析法(一)