我有一个 Android 应用程序,它使用了一种非常常见的设计模式:
- 主要 Activity 本质上是呈现对象列表 - 在小型设备上,它通过托管显示此列表的回收 View 的单个 fragment 来实现。在较大的设备上,它托管两个 fragment ,一个具有相同的对象回收 View ,另一个将在列表中选择一个对象时托管单个对象的详细信息。
- 在较小的设备上,当从列表中做出选择时,将启动一个 Activity ,该 Activity 承载一个 fragment ,该 fragment 利用 ViewPager 允许“滑动”对象列表,并在适当的位置编辑每个对象。
在这两种情况下,用户只能从详细信息 fragment 进行编辑。
我目前在应用程序类中初始化了我的 Realm 实例,然后在我用来保存一些管理方法的 Activity 基类中检索默认实例:
public abstract class SingleFragmentActivity extends AppCompatActivity {
private Realm realm;
protected abstract Fragment createFragment();
@LayoutRes
protected int getLayoutResId() {
return R.layout.activity_fragment;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
realm = Realm.getDefaultInstance();
// Initialize ProfileLab
ProfileLab.get(realm);
setContentView(getLayoutResId());
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = createFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if ( realm != null) {
realm.close();
}
}
}
请注意,我将此 Realm 实例存储在静态类“ProfileLab”中:
// Initialize ProfileLab
ProfileLab.get(realm);
然后在更新数据的各种 fragment 中,我正在做类似的事情:
mProfile = ProfileLab.get().getProfile(profileId);
*
* do CRUD activities here for example:
*
private void deleteProfile() {
ProfileLab.get().deleteProfile(mProfile);
mCallbacks.onProfileUpdated(mProfile);
}
然后在 ProfileLab 中,它看起来像:
public boolean deleteProfile(配置文件 c){ bool retVal = true;
try {
mRealm.beginTransaction();
c.deleteFromRealm();
} catch (Exception e) {
retVal = false;
} finally {
if ( mRealm != null ) {
if (retVal) {
mRealm.commitTransaction();
} else {
mRealm.cancelTransaction();
}
}
}
return (retVal);
我的问题 - 在整个应用程序的使用过程中,基本上保持 Realm 实例像这样打开是不是一个问题?我在文档中注意到了这一段:
If you get a Realm instance from a thread that does not have a Looper attached, then objects from such instance will not be updated unless the waitForChange() method is called. It is important to note that having to hold on to an old version of your data is expensive in terms of memory and disk space and the cost increases with the number of versions between the one being retained and the latest. This is why it is important to close the Realm instance as soon as you are done with it in the thread.
问题是,我并没有“完成它”,因为这是在 UI 线程上,它显然在我的应用程序的整个生命周期中运行。
我不能仅仅为了原子更新而真正打开/关闭 Realm 实例,因为我需要使用初始查询的结果来显示要从中选择编辑的对象列表 - 当我最初尝试这样做时(我在 ProfileLab 本身的每个方法中打开/关闭了 Realm 对象)我的回收器适配器中出现错误,表明 Realm 已关闭...
显示使用回收器 View 的示例代码显示了在单个 Activity 级别检索/使用/关闭的 Realm ,如果我在两个简单的 Activity (托管 RecyclerView 和托管 ViewPager)之间这样做,数据会更新吗相互反射(reflect)?
最佳答案
建议在 try/catch block 中打开和关闭 Realm 。例如:
try {
Realm realm = Realm.getDefaultInstance();
//Use the realm instance
}catch(Exception e){
//handle exceptions
}finally {
realm.close();
}
这是使用时的一个基本示例。如果能在AsyncTask中关闭就更好了。
official documentation指的是如果你使用minSdkVersion >= 19和Java >= 7,你不会手动关闭它。
try (Realm realm = Realm.getDefaultInstance()) {
// No need to close the Realm instance manually
}
关于android - 打开/关闭 Realm 实例的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42322284/