前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >flutter_xupdate 让你一键实现flutter应用版本更新

flutter_xupdate 让你一键实现flutter应用版本更新

作者头像
xuexiangjys
发布2022-04-18 13:03:45
5.7K1
发布2022-04-18 13:03:45
举报
文章被收录于专栏:我的Android开源之旅

前言

自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

演示

  • 默认版本更新
  • 支持后台更新
  • 屏幕宽高比限制显示更新
  • 强制更新
  • 自定义更新提示弹窗样式

集成指南

添加引用依赖

在你的flutter项目中的pubspec.yaml文件中添加flutter_xupdate依赖.

  • 方法一: pub集成
代码语言:javascript
复制
dependencies:
  flutter_xupdate: ^1.0.0
  • 方法二: github集成
代码语言:javascript
复制
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, 例如:

代码语言:javascript
复制
<resources>
    <style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>
</resources>

初始化

  • 调用FlutterXUpdate.init方法进行初始化.
  • 调用FlutterXUpdate.setErrorHandler方法设置错误监听.
代码语言:javascript
复制
import 'package:flutter_xupdate/flutter_xupdate.dart';

   ///初始化
   void initXUpdate() {
     if (Platform.isAndroid) {
       FlutterXUpdate.init(
         ///是否输出日志
         debug: true,
         ///是否使用post请求
         isPost: false,
         ///post请求是否是上传json
         isPostJson: false,
         ///是否开启自动模式
         isWifiOnly: false,
         ///是否开启自动模式
         isAutoMode: false,
         ///需要设置的公共参数
         supportSilentInstall: false,
         ///在下载过程中,如果点击了取消的话,是否弹出切换下载方式的重试提示弹窗
         enableRetry: false
       ).then((value) {
         updateMessage("初始化成功: $value");
       }).catchError((error) {
         print(error);
       });

       FlutterXUpdate.setErrorHandler(
           onUpdateError: (Map<String, dynamic> message) async {
         print(message);
         setState(() {
           _message = "$message";
         });
       });
     } else {
       updateMessage("ios暂不支持XUpdate更新");
     }
   }

混淆配置

混淆配置文件可参考混淆配置样例。如果不开启混淆的话可以忽略.

代码语言:javascript
复制
# XUpdate需要配置的内容
#gson
-keepattributes Signature
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
# xupdate
-keep class com.xuexiang.xupdate.entity.** { *; }

使用说明

版本更新返回的Json格式

代码语言:javascript
复制
{
  "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加密。
}

版本更新

  • 默认更新
代码语言:javascript
复制
FlutterXUpdate.checkUpdate(url: _updateUrl);
  • 默认App更新 + 支持后台更新
代码语言:javascript
复制
FlutterXUpdate.checkUpdate(url: _updateUrl, supportBackgroundUpdate: true);
  • 调整宽高比显示的版本更新
代码语言:javascript
复制
FlutterXUpdate.checkUpdate(url: _updateUrl, widthRatio: 0.6);
  • 自动模式下版本更新, 如果需要完全无人干预,自动更新,需要root权限【静默安装需要】
代码语言:javascript
复制
FlutterXUpdate.checkUpdate(url: _updateUrl, isAutoMode: true);
  • 下载时点击取消允许切换下载方式
代码语言:javascript
复制
FlutterXUpdate.checkUpdate(
      url: _updateUrl,
      overrideGlobalRetryStrategy: true,
      enableRetry: true,
      retryContent: "Github下载速度太慢了,是否考虑切换蒲公英下载?",
      retryUrl: "https://www.pgyer.com/flutter_learn");

自定义Json解析

1.定义一个自定义的版本更新解析器

代码语言:javascript
复制
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.

代码语言:javascript
复制
FlutterXUpdate.checkUpdate(url: _updateUrl3, isCustomParse: true);

直接传入UpdateEntity进行更新

代码语言:javascript
复制
///直接传入UpdateEntity进行更新提示
void checkUpdate8() {
    FlutterXUpdate.updateByInfo(updateEntity: customParseJson(_customJson));
}

自定义版本更新提示弹窗样式

目前只支持主题色和顶部图片的自定义

1.配置顶部图片的资源路径, 路径: android/app/src/main/res/values/drawable, 千万不要放到mipmap文件下,否则资源将找不到。例如:

2.调用checkUpdate方法,并设置themeColortopImageResbuttonTextColor 参数。

代码语言:javascript
复制
///自定义更新弹窗样式
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如下:
代码语言:javascript
复制
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, 按需进行打包。
代码语言:javascript
复制
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
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 我的Android开源之旅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 演示
  • 集成指南
    • 添加引用依赖
      • Android设置
        • 初始化
        • 混淆配置
        • 使用说明
          • 版本更新返回的Json格式
            • 版本更新
              • 自定义Json解析
                • 直接传入UpdateEntity进行更新
                  • 自定义版本更新提示弹窗样式
                  • 属性值
                    • 初始化
                      • 版本更新
                        • 1.问:为什么我在调试的使用是能正常更新的,但是使用flutter build apk --release打出来的包却不能正常更新?
                        • 2.问:如果我使用android的原生打包方式,如何减小包的体积呢?
                        • 3.问:配置了ApkMd5字段,为什么安装的时候还是报Code:5000, msg:安装APK失败!(apk文件校验不通过!)呢?
                        • 4.问:为什么我最新的应用下载了,但是点击安装按钮后一直提示更新失败呢?
                    • 常见问题
                    • 错误码
                    • 关联链接
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档