Flutter解析服务器SDK延迟初始化错误:查询数据时ParseObject上字段'_instance@597240915'

iswrvxsc  于 2022-11-30  发布在  Flutter
关注(0)|答案(1)|浏览(74)

我想使用Parse_server_sdk查询数据,但收到此错误[错误:flutter/runtime/dart_vm_initializer. cc(41)]未处理的异常:延迟初始化错误:字段'_instance@597240915'尚未初始化。
它只发生在我调用initState()的方法时,但如果我在elevatedButton中测试onPressed时,它可以被调用而没有错误。我不知道是什么问题,请有人帮助我。
这是调用查询的主屏幕代码:

import 'package:flutter/material.dart';
import 'package:flutter_simple_cms/api/parse_services.dart';
import 'package:flutter_simple_cms/screens/update_post_screen.dart';
import 'package:flutter_simple_cms/widgets/show_drawer.dart';
import 'package:flutter_simple_cms/widgets/show_snackbar.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  List<ParseObject> getPostList = [];

  Future<List<ParseObject>>? testGetPost;
  bool isDeleting = false;

  @override
  void initState() {
    super.initState();
    getDataTest();
  }

  void getDataTest() async {
    testGetPost = ParseService().getPostsFuture();
    print(testGetPost);
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Home'),
        ),
        drawer: showDrawer(context),
        body: testBody(),
      ),
    );
  }

  Widget testBody() {
    return SizedBox(
      height: MediaQuery.of(context).size.height,
      width: MediaQuery.of(context).size.width,
      child: Center(
        child: ElevatedButton(
          child: const Text('test'),
          onPressed: () {
            getDataTest();
          },
        ),
      ),
    );
  }

  Widget _body() {
    return SizedBox(
      height: MediaQuery.of(context).size.height,
      width: MediaQuery.of(context).size.width,
      child: StreamBuilder<List<ParseObject>>(
        initialData: getPostList,
        stream: ParseService().getPosts(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: SizedBox(
                height: 75.0,
                width: 75.0,
                child: CircularProgressIndicator(),
              ),
            );
          } else if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              return Center(
                  child: ElevatedButton(
                child: const Text("Refresh"),
                onPressed: () {
                  setState(() {});
                },
              ));
            }
            if (snapshot.hasData) {
              if (snapshot.data!.isEmpty) {
                return const Center(
                  child: Text('NO DATA', style: TextStyle(fontSize: 36.0)),
                );
              }
              return ListView.builder(
                padding: const EdgeInsets.only(top: 10.0),
                itemCount: snapshot.hasData ? snapshot.data!.length : 1,
                itemBuilder: (BuildContext context, int index) {
                  if (snapshot.data!.isEmpty) {
                    return SizedBox(
                      width: MediaQuery.of(context).size.width,
                      height: MediaQuery.of(context).size.height,
                      child: const Center(
                        child: Text(
                          'Data is Empty!',
                          style: TextStyle(fontSize: 36.0),
                        ),
                      ),
                    );
                  }
                  final postData = snapshot.data![index];
                  ParseFile? postImageCover =
                      snapshot.data![index].get<ParseFile>('postImageCover');
                  final postTitle = postData.get<String>('postTitle')!;
                  final postContent = postData.get<String>('postContent')!;
                  return Card(
                    elevation: 7.0,
                    clipBehavior: Clip.hardEdge,
                    shape: RoundedRectangleBorder(
                      side: BorderSide(
                        color: Theme.of(context).colorScheme.primaryContainer,
                        width: 1.5,
                      ),
                      borderRadius:
                          const BorderRadius.all(Radius.circular(15.0)),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Container(
                            alignment: Alignment.centerRight,
                            child: PopupMenuButton(
                              itemBuilder: (context) {
                                return [
                                  PopupMenuItem(
                                    value: 0,
                                    child: Row(
                                      children: const [
                                        Icon(Icons.edit_note),
                                        SizedBox(
                                          // sized box with width 10
                                          width: 10,
                                        ),
                                        Text("Edit post")
                                      ],
                                    ),
                                  ),
                                  PopupMenuItem(
                                    value: 1,
                                    child: Row(
                                      children: const [
                                        Icon(Icons.delete),
                                        SizedBox(
                                          // sized box with width 10
                                          width: 10,
                                        ),
                                        Text("Delete post")
                                      ],
                                    ),
                                  ),
                                ];
                              },
                              onSelected: (value) {
                                if (value == 0) {
                                  Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                      builder: (context) =>
                                          UpdatePost(postObject: postData),
                                    ),
                                  );
                                } else {
                                  isDeleting = true;
                                  ParseService()
                                      .deletePost(postData.objectId)
                                      .then((response) {
                                    if (response.success) {
                                      setState(() => isDeleting = false);
                                      showSnackbar(
                                        context,
                                        'Post Deleted!',
                                        Colors.greenAccent,
                                        Icons.check_circle_outline,
                                        Colors.greenAccent,
                                      );
                                    } else {
                                      isDeleting = false;
                                      showSnackbar(
                                        context,
                                        response.error?.message,
                                        Colors.red,
                                        Icons.error_outline,
                                        Colors.red,
                                      );
                                    }
                                  });
                                }
                              },
                            ),
                          ),
                          addSpace(10.0),
                          Visibility(
                            visible: postImageCover != null,
                            child: SizedBox(
                              width: MediaQuery.of(context).size.width,
                              height: 300.0,
                              child: postImageCover == null
                                  ? null
                                  : Image.network(
                                      loadingBuilder:
                                          (context, child, loadingProgress) {
                                        if (loadingProgress == null) {
                                          return child;
                                        }
                                        return const Center(
                                          child: SizedBox(
                                            height: 50.0,
                                            width: 50.0,
                                            child: CircularProgressIndicator(),
                                          ),
                                        );
                                      },
                                      postImageCover.url!,
                                      fit: BoxFit.cover,
                                    ),
                            ),
                          ),
                          addSpace(10.0),
                          Text(
                            postTitle,
                            textAlign: TextAlign.center,
                            style: const TextStyle(fontSize: 20.0),
                          ),
                          addSpace(10.0),
                          Text(
                            postContent,
                            textAlign: TextAlign.center,
                            style: const TextStyle(fontSize: 16.0),
                          ),
                          addSpace(5.0),
                        ],
                      ),
                    ),
                  );
                },
              );
            } else {
              return const Center(
                child: Text('NO DATA', style: TextStyle(fontSize: 36.0)),
              );
            }
          } else {
            return Text('State: ${snapshot.connectionState}');
          }
        },
      ),
    );
  }

  Widget addSpace(double? heightVal) => SizedBox(height: heightVal);
}

这是主屏幕调用的查询方法:

Future<List<ParseObject>> getPostsFuture() async {
    QueryBuilder<ParseObject> queryPosts =
        QueryBuilder<ParseObject>(ParseObject('PostList'));
    final ParseResponse apiResponse = await queryPosts.query();

    if (apiResponse.success && apiResponse.results != null) {
      return Future.value(apiResponse.results as List<ParseObject>);
    } else {
      return [];
    }
  }

我还尝试将其放在FutureBuilder上,认为查询无法在initState中调用,这很奇怪,因为很久以前,在flutter和Parse_server_sdk的旧版本上,当在initState中调用查询时,我的其他应用程序没有问题,但即使使用FutureBuilder,查询仍然无法在第一次构建时调用,它在snapshot.hasError.上卡住了。我将其更改为streamBuilder,但在第一次构建时也是如此,因此我只是放置了一个按钮来刷新,以获取第一次启动/构建时的数据

z9smfwbn

z9smfwbn1#

我自己设法修好了,所以我会给任何遇到类似问题的人我的答案。首先,类ParseObject出现LateInitializationError的问题是因为Parse.initialize还没有完成,但类homescreen.dart立即被调用,可能是因为Parse.initialize在他自己的类上。所以对于像我一样的人,你可以把Parse.initialize放在它上面。如果你有同样的问题,这可能会有帮助。
所以为了解决这个问题,我首先将Parse.initialize打开的类改为Future,以返回Parse类的值。
就像这样:

import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';

class ApiServices {
  // testing database
  final String keyApplicationId = "Your App ID";
  final String keyClientKey = "Your client key";
  final String keyParseServerUrl = "https://parseapi.back4app.com/";

  Future<Parse> initialize() async { //on this line
    return Parse().initialize(
      keyApplicationId,
      keyParseServerUrl,
      debug: true,
      clientKey: keyClientKey,
      coreStore: await CoreStoreSharedPrefsImp.getInstance(),
    );
  }
}

然后在main.dart文件上修改void main()中的Parse.initialize。
就像这样:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  ApiServices().initialize().then((value) {//on this line
    if (value.hasParseBeenInitialized()) {//and you need to add this
      runApp(const MyApp());
    }
  });
}

我希望我的回答能有所帮助

相关问题