![60bad34996680fc46637ca83c2cce476.png](https://i-blog.csdnimg.cn/blog_migrate/33d1c53e81fa86d4f6287c15f8734c83.png)
![39bbe6bf8d169d72622d917dadf6c0fa.png](https://i-blog.csdnimg.cn/blog_migrate/9d7794551225c2c2d4904063ef8f67e6.png)
点击上方蓝字关注我们
前言
自2018年我开源了XUpdate之后,至今已迭代了14个版本,月下载量达7k+,Github的star量也已经有1.1k+.
最近在研究Flutter,于是就随手写了一个Flutter小项目练练手,在写的时候我就发现,目前并没有非常好用的版本更新Flutter插件,尝试了使用Bugly的版本更新Flutter插件,但是效果非常不好.然后百度了一下,基本上都是如下方案:
- 1.使用
package_info
插件获取当前应用的版本信息 - 2.使用
dio
插件进行网络请求获取最新版本信息 - 3.使用
flutter_downloader
插件下载最新APP并安装
我想了一下,这实在是太麻烦了,要知道我的XUpdate把这些都已经做好了,只需要一行代码就可以实现应用内的版本更新,不仅如此我们完全没必要把这个几乎通用的功能在自己的应用内再实现一遍.
为此我仔细研究了一下Flutter的插件开发,用了不到1天的时间,就把XUpdate的绝大多数功能在Flutter插件上实现了,这下我就可以舒舒服服地使用一行代码来实现版本更新了!
下面我给出flutter_xupdate
插件的地址:
https://pub.dev/packages/flutter_xupdate
![175d3c693ef1a4b0785aa3d7d40ed50c.png](https://i-blog.csdnimg.cn/blog_migrate/2aaa4d64da3d78bcbba780f66ff85fe3.png)
演示
- 默认版本更新
![ad711d73b2232a4b65570593d7a3be85.png](https://i-blog.csdnimg.cn/blog_migrate/aae968d856a60871e1d52fa5bc68b270.png)
- 支持后台更新
![c35e8acd52a96aa496647b3841e4bfa4.png](https://i-blog.csdnimg.cn/blog_migrate/f39185ea70a4036f452b70e598ab87ac.png)
- 屏幕宽高比限制显示更新
![c3ea0e5d6f4c2aae829215ae3ad0dbc9.png](https://i-blog.csdnimg.cn/blog_migrate/e3c9c4122cb824d220b7c29ed6eb77ca.png)
- 强制更新
![29f649293fb279400a073f56abfe73bc.png](https://i-blog.csdnimg.cn/blog_migrate/61361fdd327eb95be91a2f2056f519fe.png)
- 自定义更新提示弹窗样式
![58fa845d4ae75ea5749c9977410e5818.png](https://i-blog.csdnimg.cn/blog_migrate/0a4bbc9fece1b7acec552f644fce4b55.png)
集成指南
添加引用依赖
在你的flutter项目中的pubspec.yaml
文件中添加flutter_xupdate
依赖.
- 方法一: pub集成
dependencies:
flutter_xupdate: ^1.0.0
- 方法二: github集成
dependencies:
flutter_xupdate:
git:
url: git://github.com/xuexiangjys/flutter_xupdate.git
ref: master
Android设置
修改Android项目的主题为AppCompat
主题,文件路径: android/app/src/main/res/values/styles.xml
, 例如:
初始化
- 调用
FlutterXUpdate.init
方法进行初始化. - 调用
FlutterXUpdate.setErrorHandler
方法设置错误监听.
'package:flutter_xupdate/flutter_xupdate.dart';
混淆配置
混淆配置文件可参考混淆配置样例。如果不开启混淆的话可以忽略.
# XUpdate需要配置的内容
使用说明
版本更新返回的Json格式
{
"Code": 0, //0代表请求成功,非0代表失败
"Msg": "", //请求出错的信息
"UpdateStatus": 1, //0代表不更新,1代表有版本更新,不需要强制升级,2代表有版本更新,需要强制升级
"VersionCode": 3, //编译版本号(唯一)
"VersionName": "1.0.2", //版本名(用于展示)
"ModifyContent": "1、优化api接口。\r\n2、添加使用demo演示。\r\n3、新增自定义更新服务API接口。\r\n4、优化更新提示界面。", //更新内容
"DownloadUrl": "https://raw.githubusercontent.com/xuexiangjys/XUpdate/master/apk/xupdate_demo_1.0.2.apk",// 文件下载地址
"ApkSize": 2048, //文件的大小(单位:kb)
"ApkMd5": "..." //md5值没有的话,就无法保证apk是否完整,每次都会重新下载。框架默认使用的是md5加密。
}
版本更新
- 默认更新
FlutterXUpdate.checkUpdate(url: _updateUrl);
- 默认App更新 + 支持后台更新
true);
- 调整宽高比显示的版本更新
FlutterXUpdate.checkUpdate(url: _updateUrl, widthRatio: 0.6);
- 自动模式下版本更新, 如果需要完全无人干预,自动更新,需要root权限【静默安装需要】
true);
- 下载时点击取消允许切换下载方式
FlutterXUpdate.checkUpdate(
url: _updateUrl,
overrideGlobalRetryStrategy: true,
enableRetry: true,
retryContent: "Github下载速度太慢了,是否考虑切换蒲公英下载?",
retryUrl: "https://www.pgyer.com/flutter_learn");
自定义Json解析
1.定义一个自定义的版本更新解析器
FlutterXUpdate.setCustomParseHandler(onUpdateParse: (String json) async {
//这里是自定义json解析
return customParseJson(json);
});
///将自定义的json内容解析为UpdateEntity实体类
UpdateEntity customParseJson(String json) {
AppInfo appInfo = AppInfo.fromJson(json);
return UpdateEntity(
hasUpdate: appInfo.hasUpdate,
isIgnorable: appInfo.isIgnorable,
versionCode: appInfo.versionCode,
versionName: appInfo.versionName,
updateContent: appInfo.updateLog,
downloadUrl: appInfo.apkUrl,
apkSize: appInfo.apkSize);
}
2.调用checkUpdate
方法,并设置isCustomParse
参数为true.
true);
直接传入UpdateEntity进行更新
///直接传入UpdateEntity进行更新提示
void checkUpdate8() {
FlutterXUpdate.updateByInfo(updateEntity: customParseJson(_customJson));
}
自定义版本更新提示弹窗样式
目前只支持主题色和顶部图片的自定义
1.配置顶部图片的资源路径, 路径: android/app/src/main/res/values/drawable
, 千万不要放到mipmap
文件下,否则资源将找不到。例如:
2.调用checkUpdate
方法,并设置themeColor
、 topImageRes
和 buttonTextColor
参数。
///自定义更新弹窗样式
void customPromptDialog() {
FlutterXUpdate.checkUpdate(url: _updateUrl, themeColor: '#FFFFAC5D', topImageRes: 'bg_update_top', buttonTextColor: '#FFFFFFFF');
}
属性值
初始化
Name | Type | Default | Description |
---|---|---|---|
debug | bool | false | 是否输出日志 |
isPost | bool | false | 是否使用post请求 |
isPostJson | bool | false | post请求是否是上传json |
isWifiOnly | bool | true | 是否只在wifi下才能进行更新 |
isAutoMode | bool | false | 是否开启自动模式 |
supportSilentInstall | bool | false | 是否支持静默安装,这个需要设备有root权限 |
enableRetry | bool | false | 在下载过程中,如果点击了取消的话,是否弹出切换下载方式的重试提示弹窗 |
retryContent | String | '' | 重试提示弹窗的提示内容 |
retryUrl | String | '' | 重试提示弹窗点击后跳转的url |
params | Map | / | 需要设置的公共参数 |
版本更新
Name | Type | Default | Description |
---|---|---|---|
url | String | / | 版本检查的地址 |
params | Map | / | 传递的参数 |
supportBackgroundUpdate | bool | false | 是否支持后台更新 |
isAutoMode | bool | false | 是否开启自动模式 |
isCustomParse | bool | false | 是否是自定义解析协议 |
themeColor | String | '' | 应用弹窗的主题色 |
topImageRes | String | '' | 应用弹窗的顶部图片资源名 |
buttonTextColor | String | '' | 按钮文字的颜色 |
widthRatio | double | / | 版本更新提示器宽度占屏幕的比例, 不设置的话不做约束 |
heightRatio | double | / | 版本更新提示器高度占屏幕的比例, 不设置的话不做约束 |
overrideGlobalRetryStrategy | bool | false | 是否覆盖全局的重试策略 |
enableRetry | bool | false | 在下载过程中,如果点击了取消的话,是否弹出切换下载方式的重试提示弹窗 |
retryContent | String | '' | 重试提示弹窗的提示内容 |
retryUrl | String | '' | 重试提示弹窗点击后跳转的url |
常见问题
1.问:为什么我在调试的使用是能正常更新的,但是使用flutter build apk --release
打出来的包却不能正常更新?
答:这里建议不要使用flutter build apk --release
进行打包。因为原生的组件使用需要配置混淆,目前使用flutter build apk --release
命令打包的话,混淆配置并不会生效(因为该指令默认使用的是R8压缩,会有问题)。
这里有三个方法可以解决:
1.使用
flutter build apk --no-shrink
指令代替。2.主动关闭R8压缩,使用D8压缩进行代替。方法就是进入到项目的
android
目录下,修改gradle.properties
如下:
org.gradle.jvmargs=-Xmx1536M
# 开启D8压缩
android.enableD8=true
android.useAndroidX=true
android.enableJetifier=true
# 关闭R8压缩
#android.enableR8=true
- 3.直接使用android的原生打包方式进行打包。方法就是进入到当前项目的android目录下,使用
./gradlew assembleRelease
命令进行打包。
2.问:如果我使用android的原生打包方式,如何减小包的体积呢?
答:
这里我们可以开启混淆,增加混淆配置,点击参考混淆配置样例。
使用gradle 配置 ndk 指定 ABI, 按需进行打包。
ndk {
abiFilters 'armeabi', 'armeabi-v7a'
// , 'arm64-v8a'
}
3.问:配置了ApkMd5字段,为什么安装的时候还是报Code:5000, msg:安装APK失败!(apk文件校验不通过!)
呢?
答:这里需要说明的是,这里填写的MD5值是APK文件进行MD5加密后的值,并不是对APK签名的MD5。框架默认使用的是MD5加密,如果你觉得不够安全,也可以使用其他加密方式,不过这可能涉及到原生的编码,详情参见:自定义文件加密校验器.
如果不想使用MD5的话就不需要配置这个字段,不过这样每次检查的话都会去重新下载APK,建议配置。
4.问:为什么我最新的应用下载了,但是点击安装
按钮后一直提示更新失败呢?
答:出现这种问题的情况有很多种。
- 首先你需要确保能否找到下载下来的最新APK,如果你设置了MD5值的话,还需要判断下载下来的最新APK计算出来的MD5值和后台接口返回的MD5值是否一致(计算文件的MD5值Demo中有对应的方法);
- 其次你需要手动安装一下APK,确保APK文件没问题(签名一致、文件完整),能正常安装;
- 最后你可以在多台设备上尝试一下,确保不是设备自身的问题。
- 如果以上方法都不能解决问题,很遗憾,那么你只能使用原生的方法来解决了。
错误码
错误码 | 备注 |
---|---|
2000 | 查询更新失败 |
2001 | 没有wifi |
2002 | 没有网络 |
2003 | 正在进行版本更新 |
2004 | 无最新版本 |
2005 | 版本检查返回空 |
2006 | 版本检查返回json解析失败 |
2007 | 已经被忽略的版本 |
2008 | 应用下载的缓存目录为空 |
3000 | 版本提示器异常错误 |
3001 | 版本提示器所在Activity页面被销毁 |
4000 | 新应用安装包下载失败 |
4001 | 读写权限申请失败 |
4002 | 取消下载 |
5000 | apk安装失败 |
5100 | 未知错误 |
关联链接
- XUpdate 一个轻量级、高可用性的Android版本更新框架: https://github.com/xuexiangjys/XUpdate
- XUpdate 使用说明文档: https://github.com/xuexiangjys/XUpdate/wiki
- XUpdate 的Flutter插件: https://github.com/xuexiangjys/flutter_xupdate
- XUpdate 的React-Native插件: https://github.com/xuexiangjys/react-native-xupdate
- XUpdate 后台管理服务: https://github.com/xuexiangjys/XUpdateService
- XUpdate 后台管理系统: https://github.com/xuexiangjys/xupdate-management
微信公众号
更多资讯内容,欢迎微信搜索公众号:「我的Android开源之旅」
![a88f48b2e44d0a25f043f6b16da6953c.png](https://i-blog.csdnimg.cn/blog_migrate/c1faa147a89e4526e8290e2affc9fc8f.jpeg)
往期推荐
技术博客,从零到数万访问,这两年我都做了什么
XPage页面框架使用详解
同样都是开发,为什么你不如别人?
Navigation和XPage相比,到底谁更香?
![1b72c6ba8bde8ca9211e08abc9e5ac6c.png](https://i-blog.csdnimg.cn/blog_migrate/3767025b53e97169258c1b1efc308378.png)
点个在看 你最好看
![3b0d9d4cac0d55cf4697007c1f97518c.png](https://i-blog.csdnimg.cn/blog_migrate/6418d9be25b0d6f0e0c9b00d367024c2.png)
![208627eea2e2aab267ccf8743e9bd8a5.png](https://i-blog.csdnimg.cn/blog_migrate/c8321a3e05a243a810fbfdcfdcb2556b.png)