zoukankan      html  css  js  c++  java
  • flutter 优雅的版本更新处理

    本人掘金文章

    思路步骤:

    1.  获取后台接口返回的最新版本的 vsersion 值! (这需要每次APP发版提审后,同时更新后台数据库App version);
    2.  使用 package_info 插件获取项目当前APP运行的 的版本号 version
    3.  后台返回的版本 version 大于 package_info 获取的 version!则弹出提示更新;
    4.  ios 跳转 AppStore 进行更新; android 则App内下载更新

    说明:

    1.  android 版本的 apk 上传到公司 oss, 生成的链接就是下载链接
    2.  可能存在的坑有, 本地开发模式下 android 下载好的apk安装不了, 提示应用签名不一致! (原因 本地开发模式并没有走 keystore签名;但是apk有; 用户从应用商店下载不会出现这情况; 或者你通过apk安装应用,在走流程测试就不会了)
    3.  使用的第三方插件有 package_info 用于获取当前版本号;flutter_xupdate 用于 android App内下载更新;
    4.  效果图见尾部

    具体代码:

    注: android 实现 App 内下载更新,我选用的是 flutter_xupdate插件并且使用的是自定义JSON的格式(灵活性较好); 插件使用方式请点击 flutter_xupdate

    homePage.dart 文件
     import './CheckUpdate.dart';
        CheckUpdate checkUpdate = CheckUpdate();
      
        // 获取版本
        Future<dynamic> initPackageInfo () async {
          PackageInfo packageInfo = await PackageInfo.fromPlatform();
          version = packageInfo.version;
        }
        
         // 检查是否需要版本更新
        void _checkUpdateVersion () async {
          await initPackageInfo();
          try {
            var response = await HttpUtil().post("app/version/detail?", 'mobile', 'json', false);
            if (response["code"] != 0) {
              setState(() {
                versionData = response["data"];
              });
              // 后台返回的版本号是带小数点的(2.8.1)所以去除小数点用于做对比
              var targetVersion = response["data"]["versionCode"].replaceAll('.', '');
              // 当前App运行版本
              var currentVersion = version.replaceAll('.', '');
              if (int.parse(targetVersion) > int.parse(currentVersion)) {
                if (Platform.isAndroid) { // 安卓弹窗提示本地下载, 交由flutter_xupdate 处理,不用我们干嘛。
                  await checkUpdate.initXUpdate();
                  checkUpdate.checkUpdateByUpdateEntity(versionData); // flutter_xupdate 自定义JSON 方式, 
                } else if (Platform.isIOS) { // IOS 跳转 AppStore
                  showIOSDialog(); // 弹出ios提示更新框
                }
              }
            }
          } catch (e) {
            print(e);
          }
        }
    CheckUpdate.dart 文件
    import 'dart:convert';
    import 'package:flutter_xupdate/flutter_xupdate.dart';
    
    class CheckUpdate{
      // 将自定义的json内容解析为UpdateEntity实体类
      UpdateEntity customParseJson(String json) {
        AppInfo appInfo = AppInfo.fromJson(json);
        return UpdateEntity(
          isForce: appInfo.isForce, // 是否强制更新
          hasUpdate: appInfo.hasUpdate, // 是否需要更新  默认true, 手动自行判断
          isIgnorable: appInfo.isIgnorable, // 是否显示 “忽略该版本”
          versionCode: appInfo.versionCode, // 新版本号
          versionName: appInfo.versionName, // 新版名称
          updateContent: appInfo.updateLog, // 新版更新日志
          downloadUrl: appInfo.apkUrl, // 新版本下载链接
          apkSize: appInfo.apkSize); // 新版本大小
      }
        // 自定义JSON更新
      checkUpdateByUpdateEntity(Map jsonData) async {
        var versionCode = jsonData["versionCode"].replaceAll('.', '');
        var updateText = jsonData["updateLog"].split('');
        var updateLog = '';
        updateText.forEach((t) {
          updateLog += '
    $t';
        });
        var rusultJson = {
          "isForce": jsonData["isForce"] == 1,
          "hasUpdate": true,
          "isIgnorable": false,
          "versionCode": int.parse(versionCode),
          "versionName": jsonData["versionName"],
          "updateLog": updateLog,
          "apkUrl": jsonData["apkUrl"],
          "apkSize":jsonData["apkSize"]
        };
        FlutterXUpdate.updateByInfo(updateEntity: customParseJson(json.encode(rusultJson)));
      }
    
      // 初始化插件
      Future<dynamic> initXUpdate () async {
        FlutterXUpdate.init(
          //是否输出日志
          debug: true,
          //是否使用post请求
          isPost: false,
          //post请求是否是上传json
          isPostJson: false,
          //是否开启自动模式
          isWifiOnly: false,
          ///是否开启自动模式
          isAutoMode: false,
          //需要设置的公共参数
          supportSilentInstall: false,
          //在下载过程中,如果点击了取消的话,是否弹出切换下载方式的重试提示弹窗
          enableRetry: false)
        .then((value) {
          print("初始化成功: $value");
        }).catchError((error) {
          print(error);
        });
        FlutterXUpdate.setUpdateHandler(
          onUpdateError: (Map<String, dynamic> message) async {
            print("初始化成功: $message");
          }, onUpdateParse: (String json) async {
            //这里是自定义json解析
            return customParseJson(json);
          });
      }
    }
    
    // 使用Dart Data Class Generator插件进行创建  使用命令: Generate from JSON
    class AppInfo {
      final bool isForce;
      final bool hasUpdate;
      final bool isIgnorable;
      final int versionCode;
      final String versionName;
      final String updateLog;
      final String apkUrl;
      final int apkSize;
    
      AppInfo({
        this.isForce,
        this.hasUpdate,
        this.isIgnorable,
        this.versionCode,
        this.versionName,
        this.updateLog,
        this.apkUrl,
        this.apkSize,
      });
    
      Map<String, dynamic> toMap() {
        return {
          'isForce': isForce,
          'hasUpdate': hasUpdate,
          'isIgnorable': isIgnorable,
          'versionCode': versionCode,
          'versionName': versionName,
          'updateLog': updateLog,
          'apkUrl': apkUrl,
          'apkSize': apkSize,
        };
      }
    
      static AppInfo fromMap(Map<String, dynamic> map) {
        if (map == null) return null;
    
        return AppInfo(
          isForce: map['isForce'],
          hasUpdate: map['hasUpdate'],
          isIgnorable: map['isIgnorable'],
          versionCode: map['versionCode']?.toInt(),
          versionName: map['versionName'],
          updateLog: map['updateLog'],
          apkUrl: map['apkUrl'],
          apkSize: map['apkSize']?.toInt(),
        );
      }
    
      String toJson() => json.encode(toMap());
    
      static AppInfo fromJson(String source) => fromMap(json.decode(source));
    
      @override
      String toString() {
        return 'AppInfo isForce: $isForce, hasUpdate: $hasUpdate, isIgnorable: $isIgnorable, versionCode: $versionCode, versionName: $versionName, updateLog: $updateLog, apkUrl: $apkUrl, apkSize: $apkSize';
      }
    }

    有疑问欢迎留言

    效果图: 左边2张为 android, 右边为 ios

                     

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 数的统计
    Java实现 蓝桥杯VIP 算法训练 和为T
    Java实现 蓝桥杯VIP 算法训练 友好数
    Java实现 蓝桥杯VIP 算法训练 连续正整数的和
    Java实现 蓝桥杯VIP 算法训练 寂寞的数
    Java实现 蓝桥杯VIP 算法训练 学做菜
    Java实现 蓝桥杯VIP 算法训练 暗恋
    Java实现 蓝桥杯VIP 算法训练 暗恋
    测试鼠标是否在窗口内,以及测试鼠标是否在窗口停留
    RichEdit 各个版本介绍
  • 原文地址:https://www.cnblogs.com/ljx20180807/p/13038654.html
Copyright © 2011-2022 走看看