Duy*_*ham 1 android realm dagger-2
我正在使用Dagger 2为整个应用程序提供单例Realm实例(所有数据访问对象都使用单个域).但是,据我所知,Realm可以使用多实例Realm.getInstance(),我们必须在完成它们时关闭每个实例,如Realm docs所示:
/**
* 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();
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:我应该像我一样使用单例Realm实例,还是为每个Activity/Fragment创建一个realm实例并使用realm.close()at 关闭它onDestroy()?
只有在给定线程上至少有1个Realm实例打开时,才能访问Managed RealmObjects(它们访问时加载延迟),但是在非looper后台线程上关闭Realm实例是非常严重的问题.
如果您从Dagger模块提供线程本地单例Realm,则该Realm实例只能在创建它的线程上访问.并且会导致从其他任何地方访问崩溃.
一种可能性是提供自己的单例类,可以打开Realm实例,如下所示:
@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.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
但即使这样,您也需要管理您需要的给定线程的本地实例.
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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
997 次 |
| 最近记录: |