Android 如何在线程上使用 Realm

mah*_*guy 5 java android realm

在我的应用程序中,我读取保存在手机上的联系人,这可能需要很长时间,然后我将其放在Thread我正在使用的嵌套中Realm,但出现此错误:

Realm access from incorrect thread. 
Realm objects can only be accessed on the thread they were created.
Run Code Online (Sandbox Code Playgroud)

我的解决方案不能解决这个问题,例如:

new Handler().post(new Runnable() {
    @Override
    public void run() {
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
            }
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

或者

new Handler(getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
            }
        });            
    }
});
Run Code Online (Sandbox Code Playgroud)

在嵌套线程上,

Epi*_*rce 7

您需要在给定线程上尝试使用 Realm 实例的实例。

new Handler(Looper.getMainLooper()).post(new Runnable() { // <-- if you are not on UI thread and want to go there
    @Override
    public void run() {
        Realm realm = null;
        try {
            realm = Realm.getDefaultInstance();
            realm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                }
            });
        } finally {
            if(realm != null) {
                realm.close();
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

尽管您不应该在 UI 线程上进行同步写入。如果您在 UI 线程上写入,请改用异步事务。

new Handler(Looper.getMainLooper()).post(new Runnable() {  // <-- if you are not on UI thread and want to go there
    @Override
    public void run() {
          final Realm realm = Realm.getDefaultInstance();
          realm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                }
            }, 
            new Realm.Transaction.OnSuccess() {
                @Override
                public void onSuccess() {
                    realm.close();
                }
            }, 
            new Realm.Transaction.OnError() {
                @Override
                public void onError(Throwable e) {
                    realm.close();
                }
            });
    }
});
Run Code Online (Sandbox Code Playgroud)

我个人更喜欢创建一个单线程执行器,在其上完成 Realm 写入。

 private final Executor executor = Executors.newSingleThreadExecutor();

 ...

 executor.execute(() -> {
     try(Realm realm = Realm.getDefaultInstance()) {
         // use Realm on background thread
     }
 });
Run Code Online (Sandbox Code Playgroud)

对于 UI 线程,您通常已经有一个通过 或 来打开/关闭的 RealmonCreate/onDestroy实例onStart/onStop