flutter版本更新常见问题大盘点

2,424 阅读7分钟

前言

在2020年新冠疫情的时候,我宅在家中无所事事,于是乎我写了一个flutter的版本更新插件: flutter_xupdate, 并且将其发布在了Google建立的Dart插件平台上,一年以来收到的反响还算不错,具体可看下图所示:

但与此同时,也收到了很多使用者的疑问.

为此,我简单看了一下问题,发现使用者之前可能压根就没有做过Android原生开发,对Android的一些基础知识非常缺乏,就会导致很多问题.

这里,为了能够让大家更好地去使用flutter_xupdate实现一键版本更新,我特地为大家盘点了使用过程中可能出现的几大问题,为大家提前排排雷.不仅如此,我还特地录了一期视频,喜欢看视频的小伙伴是不是赶紧三连支持一下呢?

视频地址如下: www.bilibili.com/video/BV1gy…


常见问题

好了,言归正传,让我们简单瞧一瞧,常见的问题都有哪些?

  • 1.无法显示版本更新弹窗。
  • 2.版本更新提示显示异常。
  • 3.下载完毕无法安装更新。
  • 4.强制更新不起作用。
  • 5.国际化问题。

下面我将一一为大家做出解答.


无法显示版本更新弹窗

出现无法显示版本更新弹窗的问题可能有多种情况. 主要的表现形式是: 更新发生报错或者显示当前无版本更新.

1.接口的问题

前提条件: 使用的框架提供的默认接口(默认更新).

请求的url没有返回默认格式的json,那样json序列化就会有问题,导致版本信息获取失败,无法判断更新状态.

因为flutter_xupdate底层调用的是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
  "ApkMd5": "..."  //应用apk的md5值没有的话,就无法保证apk是否完整,每次都会重新下载。框架默认使用的是md5加密。
}

以上字段有任何一个不符合的都有可能导致json解析失败,无法显示版本更新弹窗. 除非你使用自定义接口或者直接传入UpdateEntity进行更新.

版本号的问题

前提条件: 使用的框架提供的默认接口(默认更新).

同样的, 使用的默认接口,返回的json格式也正常,也能正常解析, 唯独是这个返回的VersionCode没有自增,导致本地版本号更新校验失败,无法显示版本更新弹窗.

混淆打包的问题

前提条件: 使用的框架提供的默认接口(默认更新),且debug运行一切正常.

出现这种情况, 主要是因为android原生项目中设置了代码混淆. 但是使用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命令进行打包。

版本更新提示显示异常

前提条件: 使用自定义更新弹窗样式, 设置了topImageRes属性.

出现的现象一般是在debug下正常显示,但是在release下却显示异常,详情如下:

出现这种问题, 主要原因是更新弹窗的顶部样式自定义使用的是反射的引用方式,所以在打release包的时候,如果我们不设置shrinkResources为false的话,打包程序就会默认清除你自定义的顶部图片,导致在release下图片不显示。

所以这个时候,我们只需要把shrinkResources显示设置为false就可以了, 具体可参考下图:

下载完毕无法安装更新

出现下载完毕无法安装更新的问题可能有多种情况. 主要的表现形式是: 无法进入到应用安装页面或者提示安装失败(签名不一致/文件解析失败).

1.apk下载的问题

如果apk没有被完整地下下来的话,或者下载下来的apk就是受损无法安装的,是肯定没法正常安装的.

所以这里我们可以先开启debug日志,然后获取到下载的apk路径,然后找到指定的文件打开看一下能否正常安装.(首先保证下载的文件是正确的).

2.MD5值设置的问题

注意这里的MD5值指的是应用APK文件的MD5值,而非应用签名文件的MD5值!!

之所以设置MD5值下载校验,就是为了防止文件下载被人篡改或者不完整,所以框架才会去对下载的APK进行MD5值的校验.

但很多人并不了解这其中的原理,所以初次使用的时候,很容易设置MD5的值是应用签名文件的MD5值,这就导致MD5值校验失败,应用无法进入到应用安装页面.

3.签名的问题

相信做过Android原生开发的人都知道,同一个包名下的应用,是不可以直接覆盖安装(更新升级)不同签名的应用的. 同包名的应用只可以覆盖安装相同签名的应用apk.

如果你debug的时候没有配置和release相同的签名,那么是不可以直接覆盖升级到release包上的.

4.设备终端的问题

因为Android的设备终端的rom以及版本都各不相同,可能在某些定制的rom机器上使用通用的apk安装方式并不起作用. 这种问题出现的概率相对较低,当上述3点都没有问题的话,可以尝试使用不同机型的机器来尝试能否安装,以排除特定设备机型的问题.

强制更新不起作用

前提条件: 使用自定义接口或者直接传入UpdateEntity进行更新.

这是因为UpdateEntity对象的isForceisIgnorable属性是互斥的.如果设置了isIgnorabletrue,这个时候再设置isForcetrue那么isForce就会失效.因为强制更新的版本是不可能可忽略的,而可忽略的版本更新也不可能是强制更新的.

国际化问题

因为flutter_xupdate底层调用的是XUpdate原生库, 更新UI是原生写的,因此要实现多语言国际化的话,需要使用原生的国际化进行配置.

错误码

最后附上常见的错误码,方便debug调试的时候发现问题.

错误码备注
2000查询更新失败
2001没有wifi
2002没有网络
2003正在进行版本更新
2004无最新版本
2005版本检查返回空
2006版本检查返回json解析失败
2007已经被忽略的版本
2008应用下载的缓存目录为空
3000版本提示器异常错误
3001版本提示器所在Activity页面被销毁
4000新应用安装包下载失败
4001读写权限申请失败
4002取消下载
5000apk安装失败
5100未知错误

最后

以上就是我整理出来的全部内容, 喜欢的小伙伴一定要记得去项目的主页: github.com/xuexiangjys… star支持一下哦~

我是xuexiangjys,一枚热爱学习,爱好编程,致力于Android架构研究以及开源项目经验分享的技术up主。获取更多资讯,欢迎微信搜索公众号:【我的Android开源之旅】