如何管理领域实例? [英] How to manage realm instance?

查看:65
本文介绍了如何管理领域实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个活动来管理多个片段和嵌套片段,像这样:

I have an Activity that manage multiples fragments and nested fragment, like that :

活动-> RootFragment1-> NestedFragment1,NestedFragment2
-> RootFragment2-> NestedFragment3,NestedFragment4 ...

Activity -> RootFragment1 -> NestedFragment1, NestedFragment2
             -> RootFragment2 -> NestedFragment3, NestedFragment4 ...

我用来获取一个领域实例,并在onStart,onStop方法的每个嵌套片段中将其关闭,但有时我遇到此异常:

I use to get a realm instance and close it in each nested fragment in onStart, onStop methods but sometimes I meet this exception :

致命异常:java.lang.IllegalStateException:此Realm实例 已经关闭,无法使用.

Fatal Exception: java.lang.IllegalStateException: This Realm instance has already been closed, making it unusable.

是否有建议的方法来获取Realm实例并将其关闭?就我而言,我应该在Activity中获取一个实例并将其传递给我的片段吗?

Is there a recommended way to get a Realm instance and close it ? In my case should I get an instance in Activity and pass it through my fragments ?

推荐答案

文档说您应该在onCreateView()/onDestroyView()中打开/关闭Realm,但是根据我的经验,片段的生命周期异常不稳定,因此我可以向您展示另外两个方法.

The docs say that you should open/close Realm in onCreateView()/onDestroyView(), but in my experience the fragment lifecycle is unusually erratic, so I can show you two other approaches.

1.)在Activity.onCreate()Activity.onDestroy()中打开/关闭领域,然后使用getSystemService()将其共享给片段(甚至是视图层次!).

1.) open/close the Realm in Activity.onCreate() and Activity.onDestroy(), then share it to the fragments (and even down the view hierarchy!) using getSystemService().

public class MyActivity extends AppCompatActivity {
    Realm realm;

    @Override
    protected void onCreate(Bundle bundle) {
        // ...
        realm = Realm.getDefaultInstance();
    }

    @Override
    protected void onDestroy() {
        realm.close();
        realm = null;
        // ...
    }

    // -----------------------------
    private static final String REALM_TAG = "__REALM__";

    public static Realm getRealm(Context context) {
        // noinspection ResourceType
        return (Realm)context.getSystemService(REALM_TAG);
    }

    @Override
    public Object getSystemService(@NonNull String name) {
        if(REALM_TAG.equals(name)) {
            return realm;
        }
        return super.getSystemService(name);
    }
}

然后分段即可

Realm realm = MyActivity.getRealm(getActivity());

您可以在视图中

Realm realm = MyActivity.getRealm(getContext());


2.)使用保留的片段作为生命周期侦听器/活动引用计数器,全局管理UI线程的Realm生命周期.


2.) manage the Realm lifecycle globally for the UI thread using retained fragment as lifecycle listener / activity reference counter.

/**
 * Created by Zhuinden on 2016.08.16..
 */
public class RealmManager {
    private static final String TAG = "RealmManager";

    static Realm realm;

    static RealmConfiguration realmConfiguration;

    public static void init(Context context) {
        Realm.init(context);
    }

    public static void initializeRealmConfig(Context appContext) {
        if(realmConfiguration == null) {
            Log.d(TAG, "Initializing Realm configuration.");
            setRealmConfiguration(new RealmConfiguration.Builder(appContext).initialData(new RealmInitialData())
                    .deleteRealmIfMigrationNeeded()
                    .inMemory()
                    .build());
        }
    }

    public static void setRealmConfiguration(RealmConfiguration realmConfiguration) {
        RealmManager.realmConfiguration = realmConfiguration;
        Realm.setDefaultConfiguration(realmConfiguration);
    }

    private static int activityCount = 0;

    public static Realm getRealm() { // use on UI thread only!
        return realm;
    }

    public static void incrementCount() {
        if(activityCount == 0) {
            if(realm != null) {
                if(!realm.isClosed()) {
                    Log.w(TAG, "Unexpected open Realm found.");
                    realm.close();
                }
            }
            Log.d(TAG, "Incrementing Activity Count [0]: opening Realm.");
            realm = Realm.getDefaultInstance();
        }
        activityCount++;
        Log.d(TAG, "Increment: Count [" + activityCount + "]");
    }

    public static void decrementCount() {
        activityCount--;
        Log.d(TAG, "Decrement: Count [" + activityCount + "]");
        if(activityCount <= 0) {
            Log.d(TAG, "Decrementing Activity Count: closing Realm.");
            activityCount = 0;
            realm.close();
            if(Realm.compactRealm(realmConfiguration)) {
                Log.d(TAG, "Realm compacted successfully.");
            }
            realm = null;
        }
    }
}

public class RealmScopeListener
        extends Fragment {
    public RealmScopeListener() {
        setRetainInstance(true);
        RealmManager.incrementCount();
    }

    @Override
    public void onDestroy() {
        RealmManager.decrementCount();
        super.onDestroy();
    }
}

还有

/**
 * Created by Zhuinden on 2016.09.04..
 */
public class RealmActivity extends AppCompatActivity {
    protected Realm realm;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        RealmManager.init(this);
        RealmManager.initializeRealmConfig(getApplicationContext());

        super.onCreate(savedInstanceState);
        RealmScopeListener realmScopeListener = (RealmScopeListener)getSupportFragmentManager().findFragmentByTag("SCOPE_LISTENER");
        if(realmScopeListener == null) {
            realmScopeListener = new RealmScopeListener();
            getSupportFragmentManager().beginTransaction().add(realmScopeListener, "SCOPE_LISTENER").commit();
        }
        realm = RealmManager.getRealm();
    }
}

这允许您为UI线程调用RealmManager.getRealm() ,其生命周期由保留片段管理.

This allows you to call RealmManager.getRealm() for the UI thread, and its lifecycle is managed by retain fragments.

这篇关于如何管理领域实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆