Realm集成Android和解决java.lang.IllegalStateException的一个想法

  • Java8
    项目build.gradle
    classpath 'io.realm:realm-gradle-plugin:10.14.0'
    模块build.gradle
    apply plugin: 'realm-android'
  • 文档参考
    https://www.mongodb.com/zh-cn/docs/atlas/device-sdks/sdk/java/quick-starts/quick-start-local/
  • Realm Studio 数据库查看工具
    https://github.com/realm/realm-studio
    http://studio-releases.realm.io/
  • 生成数据库文件(默认)位置
    /data/data/com.wego.wisdom/files/default.realm
    /data/data/com.wego.wisdom/files/default.realm.lock
    /data/data/com.wego.wisdom/files/default.realm.management
    /data/data/com.wego.wisdom/files/default.realm.note
  • java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.这个异常打算使用同一个线程解决,这样就可以在任意地方使用,提取了一个工具类进行参考。
  • import android.content.Context;
    
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    import io.realm.Realm;
    import io.realm.RealmConfiguration;
    import io.realm.exceptions.RealmMigrationNeededException;
    
    public class RealmUtils {
        // 实例对象
        private static Realm uiThreadRealm;
        // 唯一线程的线程池
        private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1, // 核心线程数
                1, // 最大线程数
                1, // 线程存活时间
                TimeUnit.MINUTES, // 时间单位
                new ArrayBlockingQueue<>(50), // 工作队列
                Executors.defaultThreadFactory(), // 线程工厂
                new ThreadPoolExecutor.AbortPolicy() // 拒绝处理程序
        );
    
        /**
         * 对外提供线程执行相关操作
         */
        public static ThreadPoolExecutor getExecutor() {
            return executor;
        }
    
        /**
         * 对外提供realm实例对象
         */
        public static Realm getRealm() {
            return uiThreadRealm;
        }
    
        /**
         * 初始化
         */
        public static void init(Context context, String realmName) {
            executor.execute(() -> {
                Realm.init(context);
                RealmConfiguration config = new RealmConfiguration.Builder()
                        .name(realmName)
                        .allowQueriesOnUiThread(true)
                        .allowWritesOnUiThread(true)
                        .build();
                try {
                    uiThreadRealm = Realm.getInstance(config);
                } catch (RealmMigrationNeededException e) {
                    // 数据库发生变化,删除原有的,再创建新的
                    Realm.deleteRealm(config);
                    uiThreadRealm = Realm.getInstance(config);
                }
            });
        }
    
        /**
         * 关闭
         */
        public static void destroy() {
            if (uiThreadRealm != null && !uiThreadRealm.isClosed()) {
                uiThreadRealm.close();
            }
        }
    }

该错误通常在使用AndroidRealm数据库时出现,可能是由于数据库升级或某些字段类型更改导致的。 解决方法是通过以下步骤进行数据库升级: 1. 停止应用程序。 2. 打开app的build.gradle文件,将Realm数据库版本号升级到一个新的版本: ``` realm { schemaVersion 1 // 原始版本号 migrationInfoSchemaVersion 1 // 新的版本号 // 如果版本号已经是2了,则升级为3 // 如果版本号已经是3了,则升级为4 // 以此类推 // ... } ``` 3. 在应用程序的Application类中,使用Realm的自动迁移方法: ``` public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); Realm.init(this); RealmConfiguration config = new RealmConfiguration.Builder() .schemaVersion(2) // 原始版本号 .migration(new MyMigration()) // 自动迁移 .build(); Realm.setDefaultConfiguration(config); } } ``` 其中,MyMigration是自定义的迁移类,用于处理数据库的升级操作。 4. 在自定义的迁移类中,使用Realm的Schema API更新数据库架构: ``` public class MyMigration implements RealmMigration { @Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { // 版本1升级到版本2 if (oldVersion == 1 && newVersion == 2) { // 更新表格 RealmSchema schema = realm.getSchema(); RealmObjectSchema objectSchema = schema.get("MyObject"); objectSchema.addField("newField", String.class); oldVersion++; } // 版本2升级到版本3 if (oldVersion == 2 && newVersion == 3) { // 更新表格 // ... oldVersion++; } // 版本3升级到版本4 if (oldVersion == 3 && newVersion == 4) { // 更新表格 // ... oldVersion++; } // ... } } ``` 在迁移类中,可以根据需要按顺序更新每个版本之间的更改。 5. 重新启动应用程序。 这样,就可以在应用程序中升级Realm数据库,并解决“cannot compact”错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值