FutureBuilder не возвращает виджет

#android #flutter

#Android #флаттер

Вопрос:

Я пытался напечатать строку изображения в кодировке base64 на своем экране после создания привязки. Ниже приведен код.

 import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';

import 'package:http/http.dart' as http;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(

        primarySwatch: Colors.blue,
     ),
     home: MyHomePage(title: 'Flutter Demo Home Page'),
   );
  }
 }

class MyHomePage extends StatefulWidget {
    MyHomePage({Key key, this.title}) : super(key: key);



    final String title;

   @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

    File _image;







     Future<String> getb64Image() async {
        List<int> imageBytes= await _image.readAsBytes();
        String b64image= base64Encode(imageBytes);
        print('In future func: $b64imagen');
         return b64image;
     }

     void clickPic() async {
       var image= await ImagePicker.pickImage(source: ImageSource.camera);
       setState(() {
         _image=image;
       });
   }

  Widget getImage(){
    return FutureBuilder<String>(
    future: getb64Image(),
    builder: (BuildContext context,AsyncSnapshot<String> snapshot){
    if(snapshot.connectionState==ConnectionState.done){
      if(snapshot.hasData){
        print('In snapshot : ${snapshot.data}');
        return new Text(snapshot.data);
      }
      else{
        return CircularProgressIndicator();
      }
    }
    else{
      return CircularProgressIndicator();
    }
  },
);
}


@override
Widget build(BuildContext context) {

 return Scaffold(
   appBar: AppBar(

    title: Text(widget.title),
  ),
  body: Center(

    child: Column(

      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[



        Center(
          child: _image!=null?getImage():Container(child: Text(
            'Click below to take a snap',
            style: Theme.of(context).textTheme.display1,
          ),),
        ),



        RaisedButton.icon(onPressed: clickPic,
            icon: Icon(Icons.camera),

            label:Text('click me to take a snap'),

        )

      ],
    ),
  ),

);
 }
 }
  

Моя версия flutter 1.2.1, и я использую Android Studio 3.3. Проблема в том, что, хотя приложение работает нормально до выполнения привязки, при попытке вывести на экран строку преобразованного изображения b64 futurebuilder ничего не создает. Приложение зависает даже без анимации CircularProgressIndicator и внезапно останавливается. Консоль не выводит никаких ошибок, кроме «Приложение завершено» или «Потеряно соединение с устройством». Строки отладки, которые я ввел в FutureBuilder и метод b64Image, работают, но единственная проблема — сбой FutureBuilder без печати строки. Пожалуйста, обратите внимание, что я запускаю приложение на эмуляторе Android.

Это ссылка на пример запуска кода в эмуляторе:https://youtu.be/291sQtow3Q4

Ниже приведен журнал консоли:

 Launching lib/main.dart on Android SDK built for x86 in debug mode...
Initializing gradle...
Resolving dependencies...
Running Gradle task 'assembleDebug'...
Built build/app/outputs/apk/debug/app-debug.apk.
Installing build/app/outputs/apk/app.apk...
I/.flutter_pylen(12574): Background young concurrent copying GC freed      3846(621KB) AllocSpace objects, 3(60KB) LOS objects, 84% free, 1103KB/7247KB, paused 214us total 119.231ms
Syncing files to device Android SDK built for x86...
I/Choreographer(12574): Skipped 92 frames!  The application may be doing too much work on its main thread.
D/EGL_emulation(12574): eglMakeCurrent: 0xdb612b40: ver 2 0 (tinfo 0xdb608da0)
I/OpenGLRenderer(12574): Davey! duration=1686ms; Flags=1,    IntendedVsync=3188489793352, Vsync=3190023126624,   OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=3190028534473, AnimationStart=3190028585003, PerformTraversalsStart=3190028607203, DrawStart=3190037234683, SyncQueued=3190038151683, SyncStart=3190052614713, IssueDrawCommandsStart=3190052729313, SwapBuffers=3190081882083,  FrameCompleted=3190190896713, DequeueBufferDuration=59694000,  QueueBufferDuration=238000, 
 D/        (12574): HostConnection::get() New Host Connection established 0xd68cab80, tid 12598
 D/        (12574): HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_dma_v1 GL_OES_vertex_array_object  GL_KHR_texture_compression_astc_ldr ANDROID_EMU_gles_max_version_2 
 D/EGL_emulation(12574): eglMakeCurrent: 0xec6e9660: ver 2 0 (tinfo 0xd67b6d40)
 D/EGL_emulation(12574): eglMakeCurrent: 0xdb612b40: ver 2 0 (tinfo 0xdb608da0)
 D/EGL_emulation(12574): eglCreateContext: 0xec6e9840: maj 2 min 0 rcv 2
 D/EGL_emulation(12574): eglMakeCurrent: 0xec6e9840: ver 2 0 (tinfo 0xd67b6c20)
 D/EGL_emulation(12574): eglMakeCurrent: 0xdb612b40: ver 2 0 (tinfo 0xdb608da0)
 D/EGL_emulation(12574): eglMakeCurrent: 0xec6e9840: ver 2 0 (tinfo 0xd67b6d40)
 I/flutter (12574): In future func: /9j/4AAQSkZJRgABAQAAAQABAAD /2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGBgYFBgYGBwkIBgcJBwYGCAsICQoKCgoKBggLDAsKDAkKCgr/2wBDAQICAgICAgUDAwUKBwYHCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgr/wAARCAUAA8ADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4 Tl5ufo6erx8vP09fb3 Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3 Pn6/9oADAMBAAIRAxEAPwDATT/FMany9RR/96Omqni9Cd6wOPpg1ttaSx5IJ oNIqzICTmvgVZn2hkC68Sw5zpsZ jmnR65qyAibQnJHdWFaxaaT5hSKzjO6P8AHFGgGYviSRCRc6LcKPUJmnL4l00/ejnX/eiNayMGGMKfwqRI7N0Je2XPemrAZCeItFfKtdbT6MC
I/flutter (12574): In snapshot : /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGBgYFBgYGBwkIBgcJBwYGCAsICQoKCgoKBggLDAsKDAkKCgr/2wBDAQICAgICAgUDAwUKBwYHCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgr/wAARCAUAA8ADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4 Tl5ufo6erx8vP09fb3 Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3 Pn6/9oADAMBAAIRAxEAPwDATT/FMany9RR/96Omqni9Cd6wOPpg1ttaSx5IJ oNIqzICTmvgVZn2hkC68Sw5zpsZ jmnR65qyAibQnJHdWFaxaaT5hSKzjO6P8AHFGgGYviSRCRc6LcKPUJmnL4l00/ejnX/eiNayMGGMKfwqRI7N0Je2XPemrAZCeItFfKtdbT6MCKs
 Application finished.
  

Проблема, с которой я сталкиваюсь, заключается в том, что ошибка не отображается. Итак, я не могу понять, в чем проблема.Кто-нибудь может мне здесь помочь?

Комментарии:

1. Вы пытаетесь показать текстовый виджет, содержащий строку, предположительно состоящую из нескольких тысяч символов. Вероятно, это бесполезно и может привести к нехватке памяти. Это действительно то, что вы хотите сделать?

2. Это действительно то, что вы хотите сделать? Да, вроде того. Моя основная цель приложения — отправить закодированное изображение на сервер, который выполняет некоторую задачу классификации и возвращает json. Я пытался распечатать строку закодированного изображения, просто чтобы проверить, работает FutureBuilder или нет. На данный момент я не завершил свой серверный код. Итак, я не могу проверить свой реальный случай. Хотя, даже текст с сервера будет иметь длину больше, чем текущая строка, которую я пытаюсь напечатать. Есть ли какой-либо другой способ справиться с этой ситуацией?

3. Так почему бы не напечатать что-нибудь разумное, например: Text('base 64 is available with length $(snapshot.data.length)')

4. Хотя это сработало, когда мне нужно будет заполнить текстовый виджет большими данными, что я и сделаю, это не сработает. Я пытался использовать RichText и TextSpan. Не повезло.

Ответ №1:

Похоже, что ваш процесс Android прерывается, поскольку виртуальной машине Dart требуется слишком много времени для отображения ваших «жирных» текстовых данных.

Вы должны видеть журналы, подобные приведенным ниже :

 03-17 20:03:55.922   712   712 I Zygote  : Process 12250 exited due to signal (9)
  

и

 I/Choreographer(20099): Skipped 72 frames!  The application may be doing too much work on its main thread.
  

найдите exited due to signal для вашего процесса в Android logcat.

По сути, Text widget could not handle string with millions of characters вероятно, он пытается отобразить слишком много текста в основном потоке за один раз.

Хотя в этом сценарии могло быть изящное сообщение разработчика от flutter, в настоящее время его нет. Возникла проблема с тем же:https://github.com/flutter/flutter/issues/29510

Комментарии:

1. Я не могу найти вкладку logcat для Android. Но сообщения журнала для приложения печатаются на вкладке «Выполнить». Хотя «завершено из-за сигнала» не упоминается, есть журнал, в котором говорится, что приложение, возможно, выполняет слишком много работы в основном потоке.