gpt4 book ai didi

android - Dagger 2 – 我应该使用单例 Realm 实例吗?

转载 作者:行者123 更新时间:2023-11-29 14:26:20 29 4
gpt4 key购买 nike

我正在使用 Dagger 2为整个应用程序提供一个单独的 Realm 实例(所有数据访问对象都使用一个单一的 Realm )。但是,据我所知,Realm 可以使用 Realm.getInstance() 拥有多个实例,我们必须在完成每个实例后关闭它,如 Realm 文档所示:

    /**
* Closes the Realm instance and all its resources.
* <p>
* It's important to always remember to close Realm instances when you're done with it in order not to leak memory,
* file descriptors or grow the size of Realm file out of measure.
*
* @throws IllegalStateException if attempting to close from another thread.
*/
@Override
public void close() {
if (this.threadId != Thread.currentThread().getId()) {
throw new IllegalStateException(INCORRECT_THREAD_CLOSE_MESSAGE);
}

if (realmCache != null) {
realmCache.release(this);
} else {
doClose();
}
}

我的问题是:我应该像以前一样使用单例 Realm 实例,还是为每个 Activity/Fragment 创建一个 realm 实例并使用 realm.close()onDestroy( )?

最佳答案

只有在给定线程上至少有 1 个打开的 Realm 实例时,Managed RealmObjects(它们在访问时是延迟加载的)才可以访问,但是在非循环后台线程上不关闭 Realm 实例是非常严重的问题。

如果您从 Dagger 模块提供线程本地单例 Realm,那么该 Realm 实例将只能在创建它的线程上访问。并且会导致从其他任何地方访问时崩溃。

一种可能性是提供一个你自己的单例类,它可以打开 Realm 实例,比如 this :

@Singleton
public class RealmManager {
private final ThreadLocal<Realm> localRealms = new ThreadLocal<>();

@Inject
public RealmManager() {
}

/**
* Opens a reference-counted local Realm instance.
*
* @return the open Realm instance
*/
public Realm openLocalInstance() {
checkDefaultConfiguration();
Realm realm = Realm.getDefaultInstance(); // <-- maybe this should be configurable
if(localRealms.get() == null) {
localRealms.set(realm);
}
return realm;
}

/**
* Returns the local Realm instance without adding to the reference count.
*
* @return the local Realm instance
* @throws IllegalStateException when no Realm is open
*/
public Realm getLocalInstance() {
Realm realm = localRealms.get();
if(realm == null) {
throw new IllegalStateException(
"No open Realms were found on this thread.");
}
return realm;
}

/**
* Closes local Realm instance, decrementing the reference count.
*
* @throws IllegalStateException if there is no open Realm.
*/
public void closeLocalInstance() {
checkDefaultConfiguration();
Realm realm = localRealms.get();
if(realm == null) {
throw new IllegalStateException(
"Cannot close a Realm that is not open.");
}
realm.close();
// noinspection ConstantConditions
if(Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()) <= 0) {
localRealms.set(null);
}
}

private void checkDefaultConfiguration() {
if(Realm.getDefaultConfiguration() == null) {
throw new IllegalStateException("No default configuration is set.");
}
}
}

但即便如此,you'd need to manage the local instances for the given threads where you need them.

public class MainActivity
extends AppCompatActivity {
RealmManager realmManager;

...

@Override
protected void onCreate(Bundle savedInstanceState) {
realmManager = Injector.get().realmManager();
realmManager.openLocalInstance();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
...
}

@Override
protected void onDestroy() {
super.onDestroy();
realmManager.closeLocalInstance();
}

关于android - Dagger 2 – 我应该使用单例 Realm 实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46334631/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com