簡體   English   中英

Android如何在線程上使用Realm

[英]Android how can i use Realm on Thread

在我的應用程序中,我讀取保存在手機上的聯系人,這可能需要很長時間,然后我把它放在Thread嵌套我正在使用Realm但我收到此錯誤:

Realm access from incorrect thread. 
Realm objects can only be accessed on the thread they were created.

我的解決方案無法解決此問題,例如:

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

要么

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

在嵌套線程上,

您需要在給定線程上嘗試使用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();
            }
        }
    }
});

雖然您不應該在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();
                }
            });
    }
});

我個人更喜歡創建一個單線程執行程序,Realm寫入完成。

 private final Executor executor = Executors.newSingleThreadExecutor();

 ...

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

對於UI線程,您通常已經通過onCreate/onDestroyonStart/onStop打開/關閉了Realm實例。

問題不在於你在不同的線程中使用Realm,問題是你在不同的線程中使用真實的instance 通常這是一個簡單的修復,類似的應該做:

Realm realmForThisThread = Realm.getDefaultInstance();
realmForThisThread.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
    }
}
...
realmForThisThread.close();

在任何線程中使用try with resources。 您不需要關閉realm實例。 它會自動關閉。

try (Realm r = Realm.getDefaultInstance()) {
    r.executeTransaction(realm -> realm.insertOrUpdate(mData));
}

您現在可以使用Realm自己的異步塊來完成工作。

realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                // Some working is here.
            }
        }, new Realm.Transaction.OnSuccess() {
            // Some proceesing lines are here.
        }, new Realm.Transaction.OnError() {
            Log.d("AsyncTransaction", "ERROR");
        });

請注意,在execute(Realm realm)方法中,您需要將此領域對象用於所有事務,而不是全局領域對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM