You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Isar状态无法持久化问题求助:需计数器APP示例解决方案

Isar持久化失效问题修复(计数器示例)

问题根源分析

你的代码存在两个核心问题导致重启后数据丢失:

  1. 每次启动强制覆盖数据:initState中每次都会将初始值为9的CounterObject写入Isar,直接覆盖了之前存储的计数数据。
  2. ID匹配错误:CounterObject使用Isar.autoIncrement作为ID,每次重启都会创建新的CounterObject实例(初始ID为0),读取时用这个新ID找不到之前存储的旧数据。

修复后的完整代码

1. main.dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isarapp/counter_schema.dart';
import 'package:isar/isar.dart';
import 'package:isarapp/home_screen.dart';
import 'package:path_provider/path_provider.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final directory = await getApplicationDocumentsDirectory();
  await Isar.open(
    [CounterObjectSchema],
    directory: directory.path,
    inspector: true,
    name: "isardb",
  );

  runApp(const MyApp());
}

class MyApp extends ConsumerWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return ProviderScope(
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Isar计数器示例',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const HomeScreen(),
      ),
    );
  }
}

2. counter_schema.dart

import 'package:isar/isar.dart';
part 'counter_schema.g.dart';

@collection
class CounterObject {
  // 固定ID为1,确保始终操作同一条数据
  Id id = 1;
  int counter;

  CounterObject({required this.counter});
}

3. home_screen.dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:isarapp/counter_schema.dart';

final counterProvider1 = StateProvider<int>((ref) {
  return 0;
});

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

  @override
  ConsumerState<ConsumerStatefulWidget> createState() => _HomeScreenState();
}

class _HomeScreenState extends ConsumerState<HomeScreen> {
  Isar? isar = Isar.getInstance("isardb");
  late CounterObject counterObject;

  // 初始化计数器:优先读取本地存储,没有则设置初始值0
  initCounter() async {
    final storedCounter = await isar?.collection<CounterObject>().get(1);
    if (storedCounter != null) {
      counterObject = storedCounter;
      ref.read(counterProvider1.notifier).state = storedCounter.counter;
    } else {
      // 首次启动,创建初始计数器
      counterObject = CounterObject(counter: 0);
      await isar?.writeTxn(
        () async => await isar?.counterObjects.put(counterObject),
      );
      ref.read(counterProvider1.notifier).state = 0;
    }
  }

  increment() async {
    counterObject.counter++;
    ref.read(counterProvider1.notifier).state = counterObject.counter;
    // 写入数据库
    await isar?.writeTxn(
      () async => await isar?.counterObjects.put(counterObject),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                ref.watch(counterProvider1).toString(),
                style: const TextStyle(fontSize: 54),
              ),
              const SizedBox(height: 30),
              GestureDetector(
                onTap: increment,
                child: Container(
                  width: 200,
                  height: 40,
                  color: Colors.blue[300],
                  child: const Center(child: Text("增加计数")),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

关键修复点说明

  • 固定数据ID:将CounterObject的ID设为固定值1,确保每次操作的都是同一条计数数据,避免因autoIncrement导致的ID不匹配问题。
  • 调整初始化逻辑:启动时先尝试读取本地存储的计数器,不存在时才创建初始值,避免每次启动覆盖已有数据。
  • 移除冗余权限:使用getApplicationDocumentsDirectory()获取的是应用私有目录,Android 10+无需额外存储权限,因此可以删除permission_handler相关代码。

内容的提问来源于stack exchange,提问作者AbdulHaseeeb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 04:25:17