我有一个使用非常常见的设计模式的Android应用程序:

  • 主要 Activity 实质上是显示对象列表-在小型设备上,它通过承载显示此列表的recyclerview的单个 fragment 来实现。在较大的设备上,它包含两个 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(Profile 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实例打开是一个问题吗?我在文档中注意到了这一段:



    关键是,我并没有做到这一点,因为它在UI线程上,该线程显然在我的应用程序的整个生命周期中都在运行。

    我不能真的仅仅为原子更新打开/关闭 Realm 实例,因为我需要使用初始查询的结果来显示要选择编辑的对象的列表-最初尝试时(我有 Realm )在ProfileLab本身的每个方法中打开/关闭对象)我的回收器适配器中出现错误,该 Realm 已关闭...

    显示使用回收站 View 的示例代码显示了在各个 Activity 级别上检索/使用/关闭的 Realm ,如果我在两个简单的 Activity (托管RecyclerView和托管ViewPager)之间进行此操作,则数据更新将反射(reflect)在彼此?

    最佳答案

    建议在try/catch块中打开和关闭 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
    }
    

    10-07 19:58
    查看更多