Флаттер различное поведение в режиме отладки и выпуска
Я разрабатываю эти функции для приложения: загрузка изображения из галереи, изменение его размера и сохранение.
Изменение размера является интенсивной операцией процессора, поэтому я следовал предложенному здесь подходу, используя изолят, чтобы улучшить взаимодействие с пользователем.
Когда я запускаю код в режиме отладки, у меня нет проблем, но когда я пытаюсь использовать тот же код в режиме выпуска, мое изображение сохраняется неправильно.
Может кто-нибудь помочь мне понять проблему, которую я объяснил, пожалуйста?
Я тестирую код только на этом устройстве: HUAWEI P9 lite VNS-L31 с Android 7.0
Вот код, чтобы повторить проблему. Это новый проект флаттера со следующими файлами:
В pubspec.yaml
Я добавляю этот раздел:
dependencies:
path_provider: ^0.4.1
image_picker: ^0.4.10
image: ^2.0.4
flutter:
sdk: flutter
Весь код в lib/main.dart
:
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:image/image.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
File _file;
Future<File> _getImage() async {
File image = await ImagePicker.pickImage(source: ImageSource.gallery);
if (image != null) {
return image;
}
return null;
}
static decode(DecodeParam param) async {
var p = await param.file.readAsBytes();
var image = decodeImage(p);
var thumbnail = copyResize(image, 120);
param.sendPort.send(thumbnail);
}
void _displayImage() async {
setState(() {
_file = null;
});
File file = await _getImage();
ReceivePort receivePort = new ReceivePort();
await Isolate.spawn(decode, new DecodeParam(file, receivePort.sendPort));
var image = await receivePort.first;
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
File profilePictureFile =
File(p.join(tempPath, 'thumbnail' + _counter.toString() + '.png'))
..writeAsBytesSync(encodePng(image));
setState(() {
_counter++;
_file = profilePictureFile;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_file != null
? Container(
height: 200.0,
width: 200.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.fitWidth, image: FileImage(_file))))
: Container(),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _displayImage,
child: new Icon(Icons.add),
),
);
}
}
class DecodeParam {
final File file;
final SendPort sendPort;
DecodeParam(this.file, this.sendPort);
}
flutter doctor -v
:
[√] Flutter (Channel master, v0.9.7-pre.61, on Microsoft Windows [Versione 10.0.15063], locale it-IT)
• Flutter version 0.9.7-pre.61 at C:\src\flutter
• Framework revision 2d81adf74c (2 days ago), 2018-10-05 22:29:37 -0700
• Engine revision 572fa5646a
• Dart version 2.1.0-dev.6.0.flutter-c6254163dc
[√] Android toolchain - develop for Android devices (Android SDK 28.0.1)
• Android SDK at d:\Profiles\alarosa\AppData\Local\Android\sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-28, build-tools 28.0.1
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02)
• All Android licenses accepted.
[√] Android Studio (version 3.1)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin version 26.0.1
• Dart plugin version 173.4700
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02)
[!] IntelliJ IDEA Community Edition (version 2018.1)
• IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.1
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
• For information about installing plugins, see
https://flutter.io/intellij-setup/#installing-the-plugins
[√] VS Code (version 1.27.2)
• VS Code at d:\Profiles\alarosa\AppData\Local\Programs\Microsoft VS Code
• Flutter extension version 2.19.0
[√] VS Code, 64-bit edition (version 1.27.2)
• VS Code at C:\Program Files\Microsoft VS Code
• Flutter extension version 2.19.0
[√] Connected device (1 available)
• HUAWEI VNS L31 • 4TE0216A14001341 • android-arm64 • Android 7.0 (API 24)
! Doctor found issues in 1 category.
1 ответ
Следуя совету @GunterZochbauer, я открыл вопрос о хранилище флаттера.
Команда Flutter работает над этим, и, как вы можете прочитать в ветке github, Джейсон-Симмонс предлагает следующую работу.
Измените отправителя на:
param.sendPort.send([thumbnail.width, thumbnail.height, thumbnail.data]);
и получатель:
List<dynamic> imageData = await receivePort.first;
var image = new Image.fromBytes(imageData[0], imageData[1], imageData[2]);
У меня было что-то подобное, но с отображением изображений, убрав расширенное, исправлено поведение.
В writeAsBytesSync
у метода есть параметры flush
, значение по умолчанию - false.
Комментарий flush
: Если для аргумента [flush] установлено значение true, записанные данные будут сброшены в файловую систему перед возвратом.
Измените свой код следующим образом:
File profilePictureFile =
File(p.join(tempPath, 'thumbnail' + _counter.toString() + '.png'))
..writeAsBytesSync(encodePng(image), flush: true);
Проверьте, не были ли изменения.
Неизолированный имеет разделение памяти. Если он изолирован, файл должен прочитать файловую систему, и содержимое файла может быть не записано или записано только наполовину.