Flutter:JSON。使用提供程序解码错误

时间:2020-02-25 02:18:12

标签: flutter dart

我想使用以下代码将API中的 MobileVersionList AppInfoList 数据从API保存到SharedPreferences中:

全球提供商


  //! Save AppInfoList To SharedPreferences
  String _encodeAppInfoList = '';
  String get encodeAppInfoList => _encodeAppInfoList;
  List get decodeAppInfoList => json.decode(_encodeAppInfoList) ?? [];
  List<AppInfoModel> get appInfoList =>
      decodeAppInfoList.map((json) => AppInfoModel.fromJson(json)).toList() ??
      [];

  Future<bool> setEncodeAppInfoList(String encodeAppInfoList) async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    final result =
        await preferences.setString(_APP_INFO_LIST, encodeAppInfoList);
    await getEncodeAppInfoList();
    print("result setEncodeAppInfoList : $result");

    notifyListeners();
    return result;
  }

  Future<String> getEncodeAppInfoList() async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    final result = preferences.getString(_APP_INFO_LIST);
    _encodeAppInfoList = result;
    notifyListeners();
    print("result getEncodeAppInfoList : $result");
    return result;
  }

  //! Save Mobile Version From Database To SharedPreferences
  String _encodeMobileVersionList = '';
  String get encodeMobileVersionList => _encodeMobileVersionList;
  List get decodeMobileVersionList =>
      json.decode(encodeMobileVersionList) ?? [];
  List<MobileVersionModel> get mobileVersionList =>
      decodeMobileVersionList
          .map((json) => MobileVersionModel.fromJson(json))
          .toList() ??
      [];

  Future<bool> setEncodeMobileVersionList(String encodeAppInfoList) async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    final result =
        await preferences.setString(_MOBILE_VERSION_LIST, encodeAppInfoList);
    await getEncodeMobileVersionList();
    print("result setEncodeMobileVersionList : $result");

    notifyListeners();
    return result;
  }

  Future<String> getEncodeMobileVersionList() async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    final result = preferences.getString(_MOBILE_VERSION_LIST);
    _encodeMobileVersionList = result;
    notifyListeners();
    print("result getEncodeMobileVersionList : $result");
    return result;
  }

移动API

Future<String> getNewestMobileVersion() async {
    try {
      final response = await http
          .get('$_baseUrl/getNewestVersion')
          .timeout(Duration(seconds: 60));
      final Map<String, dynamic> responseJson = json.decode(response.body);
      if (responseJson["status"] == "ok") {
        List mobileVersionList = responseJson["data"];
        String encodeMobileVersionList = jsonEncode(mobileVersionList);
        return encodeMobileVersionList;
      } else {
        throw CustomError(responseJson['message']);
      }
    } catch (e) {
      return Future.error(e.toString());
    }
  }

AppInfo API

Future<String> getLogoClient() async {
    try {
      final response = await http.get("$_baseUrl/getLogoClient").timeout(
            const Duration(seconds: 60),
          );
      final Map<String, dynamic> responseJson = json.decode(response.body);
      if (responseJson["status"] == "ok") {
        List image = responseJson["data"];
        String encodeAppInfoList = jsonEncode(image);

        return encodeAppInfoList;
      } else {
        throw CustomError(responseJson["message"]);
      }
    } catch (e) {
      return Future.error(e.toString());
    }
  }

一切正常,我可以看到将数据保存到sharedpreferences的结果是成功的:

I/flutter ( 3897): result getEncodeMobileVersionList : [{"id":"3","version":"1.0.2","release":"0000-00-00","status":"0","change_log":"","target":"","created_by":"0","created_at":"0000-00-00 00:00:00","updated_by":null,"updated_at":null}]
I/flutter ( 3897): result getEncodeAppInfoList : [{"kodeInfo":"1","namaInfo":"Integrasi Operasional Outlet","keteranganInfo":"Burger Klenger ERPOS Version 1.2","fileInfo":"img-1.png","logoInfo":"logo-1.png","loginBackgroundInfo":"bfront-1.png","loginLeftInfo":"bleft-1.png","loginSupportInfo":"bsupport-1.png","createBy":"","createTime":"0000-00-00 00:00:00","updateBy":"hambaallah","updateTime":"2020-02-09 06:32:57"}]

但是问题是,每次我加载我的SplashScreen时(我将它们保存在SplashScreen中),都会收到错误消息:

错误

I/flutter ( 3897): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 3897): The following FormatException was thrown building SplashScreen(dirty, dependencies:
I/flutter ( 3897): [_LocalizationsScope-[GlobalKey#5b1c0], _InheritedTheme,
I/flutter ( 3897): _DefaultInheritedProviderScope<GlobalProvider>], state: _SplashScreenState#a043f):
I/flutter ( 3897): Unexpected end of input (at character 1)
I/flutter ( 3897):
I/flutter ( 3897): ^
I/flutter ( 3897):
I/flutter ( 3897): The relevant error-causing widget was:
I/flutter ( 3897):   SplashScreen 
lib\main.dart:55
I/flutter ( 3897):
I/flutter ( 3897): When the exception was thrown, this was the stack:
I/flutter ( 3897): #0      _ChunkedJsonParser.fail  (dart:convert-patch/convert_patch.dart:1394:5)
I/flutter ( 3897): #1      _ChunkedJsonParser.close  (dart:convert-patch/convert_patch.dart:512:7)
I/flutter ( 3897): #2      _parseJson  (dart:convert-patch/convert_patch.dart:32:10)
I/flutter ( 3897): #3      JsonDecoder.convert  (dart:convert/json.dart:495:36)
I/flutter ( 3897): #4      JsonCodec.decode  (dart:convert/json.dart:153:41)
I/flutter ( 3897): #5      GlobalProvider.decodeMobileVersionList 
package:global_template/providers/global_provider.dart:229
I/flutter ( 3897): #6      GlobalProvider.mobileVersionList 
package:global_template/providers/global_provider.dart:231
I/flutter ( 3897): #7      _SplashScreenState.build 
package:klenger_burger_app/screens/splash_screen.dart:52
I/flutter ( 3897): #8      StatefulElement.build 
package:flutter/…/widgets/framework.dart:4590
I/flutter ( 3897): #9      ComponentElement.performRebuild 
package:flutter/…/widgets/framework.dart:4478
I/flutter ( 3897): #10     StatefulElement.performRebuild 
package:flutter/…/widgets/framework.dart:4646
I/flutter ( 3897): #11     Element.rebuild 
package:flutter/…/widgets/framework.dart:4202
I/flutter ( 3897): #12     ComponentElement._firstBuild 
package:flutter/…/widgets/framework.dart:4461
I/flutter ( 3897): #13     StatefulElement._firstBuild 
package:flutter/…/widgets/framework.dart:4637
I/flutter ( 3897): #14     ComponentElement.mount 
package:flutter/…/widgets/framework.dart:4456
I/flutter ( 3897): ...     Normal element mounting (115 frames)
I/flutter ( 3897): #129    Element.inflateWidget 
package:flutter/…/widgets/framework.dart:3430
I/flutter ( 3897): #130    MultiChildRenderObjectElement.mount 
package:flutter/…/widgets/framework.dart:5857
I/flutter ( 3897): ...     Normal element mounting (253 frames)
I/flutter ( 3897): #383    Element.inflateWidget 
package:flutter/…/widgets/framework.dart:3430
I/flutter ( 3897): #384    Element.updateChild 
package:flutter/…/widgets/framework.dart:3198
I/flutter ( 3897): #385    ComponentElement.performRebuild 
package:flutter/…/widgets/framework.dart:4498
I/flutter ( 3897): #386    _InheritedProviderScopeMixin.performRebuild 

package:provider/src/inherited_provider.dart:220
I/flutter ( 3897): #387    Element.rebuild 
package:flutter/…/widgets/framework.dart:4202
I/flutter ( 3897): #388    ComponentElement._firstBuild 
package:flutter/…/widgets/framework.dart:4461
I/flutter ( 3897): #389    ComponentElement.mount 
package:flutter/…/widgets/framework.dart:4456
I/flutter ( 3897): ...     Normal element mounting (7 frames)
I/flutter ( 3897): #396    SingleChildWidgetElementMixin.mount 
package:nested/nested.dart:223
I/flutter ( 3897): ...     Normal element mounting (7 frames)
I/flutter ( 3897): #403    _NestedHookElement.mount 
package:nested/nested.dart:188
I/flutter ( 3897): ...     Normal element mounting (7 frames)
I/flutter ( 3897): #410    SingleChildWidgetElementMixin.mount 
package:nested/nested.dart:223
I/flutter ( 3897): #411    Element.inflateWidget 
package:flutter/…/widgets/framework.dart:3430
I/flutter ( 3897): #412    Element.updateChild 
package:flutter/…/widgets/framework.dart:3198
I/flutter ( 3897): #413    RenderObjectToWidgetElement._rebuild 
package:flutter/…/widgets/binding.dart:1142
I/flutter ( 3897): #414    RenderObjectToWidgetElement.mount 
package:flutter/…/widgets/binding.dart:1113
I/flutter ( 3897): #415    RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> 
package:flutter/…/widgets/binding.dart:1055
I/flutter ( 3897): #416    BuildOwner.buildScope 
package:flutter/…/widgets/framework.dart:2591
I/flutter ( 3897): #417    RenderObjectToWidgetAdapter.attachToRenderTree 
package:flutter/…/widgets/binding.dart:1054
I/flutter ( 3897): #418    WidgetsBinding.attachRootWidget 
package:flutter/…/widgets/binding.dart:935
I/flutter ( 3897): #419    WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> 
package:flutter/…/widgets/binding.dart:917
I/flutter ( 3897): (elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)
I/flutter ( 3897):
I/flutter ( 3897): ════════════════════════════════════════════════════════════════════════════════════════════════════

SplashScreen

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    if (mounted) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        fetchAppInfo();
        fetchMobileVersion();
      });
    }
    return null;
  }

  fetchAppInfo() async {
    final globalProvider = Provider.of<GlobalProvider>(context, listen: false);
    final result = await appInfoApi.getLogoClient();
    await globalProvider.setEncodeAppInfoList(result);
  }

  void fetchMobileVersion() async {
    final globalProvider = Provider.of<GlobalProvider>(context, listen: false);
    final result = await mobileVersionApi.getNewestMobileVersion();
    await globalProvider.setEncodeMobileVersionList(result);
  }

  @override
  Widget build(BuildContext context) {
    final globalProvider = Provider.of<GlobalProvider>(context);
    // final appInfoList = globalProvider.appInfoList;
    // final mobileVersionList = globalProvider.mobileVersionList;
    return Scaffold(
      backgroundColor: Theme.of(context).primaryColor,
      body: (globalProvider.encodeMobileVersionList == null ||
              globalProvider.encodeAppInfoList == null)
          ? LoadingFutureBuilder()
          : (globalProvider.mobileVersionList[0].version !=
                  globalProvider.versionPackageInfo)
              ? Center(
                  child: AlertDialog(
                    title: Text('Newest APK Available'),
                    content: Text('Changelog \n 1.Fixed Bug'),
                    actions: <Widget>[
                      FlatButton(onPressed: () => "", child: Text('Copy Link')),
                      FlatButton(
                          onPressed: () => "",
                          child: Text('Download Newest APK'))
                    ],
                  ),
                )
              : SplashScreenTemplate(
                  image: SplashScreenImage(
                      imageUrl:
                          "${appInfoApi.baseImageUrl}/${globalProvider.appInfoList[0].fileInfo}"),
                  navigateAfterSplashScreen:
                      (globalProvider.encodeUserList == null)
                          ? LoginScreen()
                          : WelcomeScreen(),
                ),
    );
  }

我认为这是因为我直接调用Provider,但是 json.decode 尚未在initState中完成。

您能帮我吗?

1 个答案:

答案 0 :(得分:0)

您不应使初始屏幕背景变重。

I/flutter ( 3897): _DefaultInheritedProviderScope<GlobalProvider>], state: _SplashScreenState#a043f): I/flutter ( 3897): Unexpected end of input (at character 1) I/flutter ( 3897): I/flutter ( 3897): ^ I/flutter ( 3897): I/flutter ( 3897): The relevant error-causing widget was: I/flutter ( 3897): SplashScreen lib\main.dart:55

从您的错误日志上方,您可以清楚地看到,某些意外的输入结束导致了此问题,并且还涉及到一个小部件。尝试调试一次,它将显示根本原因。尝试在初始状态和支架内部的主体处添加断点。一旦尝试过,请告诉我。乐于助人,乐于编码。