Flutter асинхронный метод замедление производительности приложения - PullRequest
3 голосов
/ 22 декабря 2019

Я новичок во флаттере и не могу понять, что я могу делать неправильно. В моем приложении пользователь может изменить изображение своего аватара. Он может выбрать изображение из галереи или сделать фотографию. Новое изображение аватара сохраняется в поле _avatarImage , а в методе setState для поля _newImage устанавливается значение true, например:

Future getNewAvatarImage() async {
   Image _image = .... // Take a photo or a image from Gallery
   // ...
   _avatarImage = _image;
   setState(
     () => _newImage = true;
   );
 }

В одномчасть кода У меня есть метод compressAndUpload , который при вызове сжимает изображение и отправляет его на удаленный сервер. Этот метод является асинхронным и вызывается в методе построения всякий раз, когда поле _newImage имеет значение true. Вот так

@override
Widget build(BuildContext context) {
    if (_newImage) {
       _newImage = false;
       compressAndUpload(_avatarImage);
    }
    return Container(
       //...
       child: _avatarImage,
       //
    );

Проблема в том, что новому образу аватара потребуется много времени для отображения при вызове метода compressAndUpload. Если этот метод закомментирован, новое изображение аватара быстро появляется.

    if (_newImage) {
       _newImage = false;
       // New image show quickly
       // compressAndUpload(_avatarImage);
    }

    ***********

    if (_newImage) {
       _newImage = false;
       // Image takes too long to appear
       compressAndUpload(_avatarImage);
    }

В чем проблема? Метод compressAndUpload является асинхронным и поэтому не должен вызывать задержку отображения нового изображения:

 Future<void> compressAndUpload(var image) async {
    // Compress image
    // upload image
 }

ОБНОВЛЕНИЕ:

Для дальнейшего пояснения я показываю полный код compressAndUpload метод:

 Future<void> compressAndUpload(var image) async {

  var imageBytes = imagem.readAsBytesSync();

  saveImageToPreferences(base64String(imageBytes));

  var tempDir = await getTemporaryDirectory();
  var path = tempDir.path;

  // Reduce size
  img.Image image = img.decodeImage(imageBytes);
  img.Image smallerImage = img.copyResize(image, width: 1000);

  File compressedFileImage =  

  File('$path\${Explika.getAluno().id}.jpg')
   ..writeAsBytesSync(img.encodeJpg(smallerImage, quality: 50));

  String _urlsegment =  Explika.producaoFlag ? 
  'https://www.remoteserver.pt' : 'http://10.0.2.2';

  var stream = http.ByteStream(DelegatingStream.typed(
               compressedFileImage.openRead()));
  var length = await compressedFileImage.length();
  var uri = Uri.parse('$_urlsegment/explika/api/upload');

  var request = http.MultipartRequest("POST", uri);

  var multipartFile = http.MultipartFile('fotoaluno', stream, length,
      filename: '${Explika.getAluno().id}.jpg');

  request.files.add(multipartFile);

  var response;
  try {
    response = await request.send();
  } catch (e) {
    // mostrar falha de rede
    //_uploadingImagem = false;
    print(e);
    return;
  }

  //Get the response from the server
  var responseData = await response.stream.toBytes();
  var responseString = String.fromCharCodes(responseData);
  print(responseString);

}

1 Ответ

1 голос
/ 22 декабря 2019

Большое спасибо за все комментарии.

Проблема была решена, когда я обнаружил, что в методе pickImage можно было установить максимальную ширину и максимальную высоту изображения. быть выбранным. Таким образом, шаг сжатия выбранного изображения не требовался.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...