我使用Dagger 2为整个应用提供单例Realm实例(所有数据访问对象都使用单个域)。但是,据我所知,Realm可以使用 @NgModule({
declarations: [
MyApp,
ExpansivoComponent
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
ExpansivoComponent
],
进行多实例,我们必须关闭每个实例,当我们完成它时,由Realm docs提供:
Realm.getInstance()
我的问题是:我应该像我一样使用单身Realm实例,还是为每个Activity / Fragment创建一个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.close()
关闭它?
答案 0 :(得分:5)
只有在给定线程上至少有1个Realm实例打开时,才能访问Managed RealmObjects(它们访问时延迟加载),但是在非looper后台线程上关闭Realm实例是非常严重的问题。 / p>
如果您从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();
}
答案 1 :(得分:4)
单例实例最有可能让您陷入困境。您应该为每个活动/片段创建一个。