План обновления приложения для проекта Flutter

Flutter

Название проекта, связанного с предыдущей статьей, по-прежнему остается пустым приложением для управления грузами. Эта статья используется для объяснения схемы обновления проектов приложений на основе Flutter. Эта статья доступна только для Android.

До того, как я связался с Flutter, я сделал относительно неудачное приложение на основе технологии DCloud HTML5+ и сделал несколько проектов RN. В этих двух схемах обновления приложений с разными механизмами RN использует технологию Microsoft CodePush. А неудачный проект - проверить номер версии и скачать установочный пакет. В этом проекте Flutter, когда я писал метод обновления приложения, при проверке данных я нашел статью, в которой примерно объяснялась возможность реализации CodePush во Flutter. Однако я не нашел возможного способа сделать это. Поэтому принято простое и грубое обновление приложения.

Работа сервера

Для того, чтобы проверить номер версии и скачать установочный пакет приложения, мы помещаем два файла в папку на сервере, первыйversion.jsonфайл, содержание:

{
    "android": "1.0.1"
}

Этот файл используется для сохранения номера версии, мы можем написать метод чтения для чтения этого номера версии:

Future<bool> checkNewVersion() async {
  try {
    final res = await http.get(downLoadUrl + '/version.json');
    if (res.statusCode == 200) {
      final Map<String, dynamic> body = json.decode(res.body);
      if (defaultTargetPlatform == TargetPlatform.android) {
        final packageInfo = await PackageInfo.fromPlatform();
        final newVersion = body['android'];
        return (newVersion.compareTo(packageInfo.version) == 1);
      }
    }
  } catch (e) {
    return false;
  }
  return false;
}

Второй файл — это установочный пакет приложения, который используется для загрузки и установки.

Работа на стороне приложения

На стороне приложения необходимо добавить множество методов, в том числе методы, которые должны обрабатывать разрешения приложения, считывать номер версии, а также загружать и устанавливать установочный пакет приложения.

доступ к разрешениям

существуетtargetSdkVersion < 24Раньше мы моглиAndroidManifest.xmlНапишите в этот файл, чтобы получить права на чтение и запись:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Но когда Flutter обновляется до версии 1.0.0, targetSdkVersion на этом этапе — 27. Версии до API 23 автоматически получали разрешения, но начиная с Android 6.0 было добавлено требование приложения разрешения, что является более безопасным. Поэтому нам нужно сделать что-то дополнительное, чтобы получить разрешение.

я здесьstackoverflowЯ нашел статью о решении этой проблемы. Метод, получивший высшую оценку в этой статье, более ответственен, так как времени относительно мало, и исследований пока нет, но начальник проектной группы сказал, что если вы хотите решить эту задачу на отлично, вам все равно надо прийти и изучить.

Я использовал второй метод в этом проекте, вМетод onCreate для MainActivity.javaдобавлено в

StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());

затем импортироватьsimple_permissionsЭто основано на запросе разрешений приложения и необходимости включения разрешений. Конкретный метод:

  //是否有权限
  Future<bool> checkPermission() async {
    bool res = await SimplePermissions.checkPermission(
        Permission.WriteExternalStorage);
    return res;
  }

  //打开权限
  Future<PermissionStatus> requestPermission() async {
    return SimplePermissions.requestPermission(Permission.WriteExternalStorage);
  }

Получить номер версии

Ставим сервер с именемversion.jsonфайл, мы можем получить содержимое этого файла для доступа к записанному в нем номеру версии:

Future<bool> checkNewVersion() async {
  try {
    final res = await http.get(downLoadUrl + '/version.json');
    if (res.statusCode == 200) {
      final Map<String, dynamic> body = json.decode(res.body);
      if (defaultTargetPlatform == TargetPlatform.android) {
        // 获取此时版本
        final packageInfo = await PackageInfo.fromPlatform();
        final newVersion = body['android'];
        // 此处比较版本
        return (newVersion.compareTo(packageInfo.version) == 1);
      }
    }
  } catch (e) {
    return false;
  }
  return false;
}

Поскольку этот проект представляет собой проект портативного терминала на базе Android 7.0, обработка запроса о том, является ли он Android, выполняется здесь.

Загрузите установочный пакет

В функции скачивания установочного пакета мы установилиflutter_downloaderэта зависимость. Сначала получите адрес загрузки и загрузите установочный пакет:

// 获取安装地址
Future<String> get _apkLocalPath async {
  final directory = await getExternalStorageDirectory();
  return directory.path;
}
// 下载
Future<void> executeDownload() async {
  final path = await _apkLocalPath;
  //下载
  final taskId = await FlutterDownloader.enqueue(
      url: downLoadUrl + '/app-release.apk',
      savedDir: path,
      showNotification: true,
      openFileFromNotification: true);
  FlutterDownloader.registerCallback((id, status, progress) {
    // 当下载完成时,调用安装
    if (taskId == id && status == DownloadTaskStatus.complete) {
      _installApk();
    }
  });
}
// 安装
Future<Null> _installApk() async {
  // XXXXX为项目名
  const platform = const MethodChannel(XXXXX);
  try {
    final path = await _apkLocalPath;
    // 调用app地址
    await platform.invokeMethod('install', {'path': path + '/app-release.apk'});
  } on PlatformException catch (_) {}
}

Установка завершена.

Суммировать

Выше приведены шаги обновления проекта Flutter. В сложной части вышеперечисленных шагов разрешение получается одним блоком, если его не установить, установочный пакет не будет успешно загружен. Я считаю, что в ближайшем будущем Flutter тоже может использовать CodePush.

Кстати, проект, который я назвал провальным, был на полпути, когда я пришел в проектную команду. Что меня шокировало, так это то, что в проекте, основанном на Vue, никто не использовал управление состоянием более чем в половине проекта.Vuex был представлен, но никто его не использовал. Ну и насильно возить, и обнаружил, что переноска не двигается. Приложив все усилия, чтобы исправить это, я наблюдал, как проект катится в пропасть. В то время я был еще новичком и хотел изучать технологии, но обнаружил, что группе людей, утверждающих, что у них более трех лет опыта, нужны я и еще один коллега, только что присоединившийся к компании. В то время я все еще был в отчаянии и мог брать их на работу только сверхурочно, пока был в отчаянии. Теперь я чувствую, что уровень и атмосфера команды проекта действительно важны! ! !

image