如何管理领域实例?
我有管理的倍数片段和嵌套片段,这样的活动:如何管理领域实例?
活动 - > RootFragment1 - > NestedFragment1,NestedFragment2
- > RootFragment2 - > NestedFragment3,NestedFragment4 ...
我使用得到一个领域实例,并在在onStart每个分片嵌套关闭它,方法的onStop但有时我遇到此异常:
致命异常:java.lang.IllegalStateException:这个领域实例 已经关闭,使其无法使用。
是否有推荐的方法来获得Realm实例并关闭它?在我的情况下,我应该在Activity中获得一个实例并将其传递给我的碎片?
该文档说你应该打开/关闭Realm在onCreateView()/onDestroyView()
,但以我的经验来说,片段生命周期异常不稳定,所以我可以告诉你另外两种方法。
1.)打开/关闭Activity.onCreate()
和Activity.onDestroy()
中的领域,然后使用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);
}
}
然后在片段您可以在UI线程做
Realm realm = MyActivity.getRealm(getActivity());
而且在视图中,你可以做
Realm realm = MyActivity.getRealm(getContext());
2)管理领域全球生命周期使用保存片段作为生命周期监听器/活动引用计数器。
/**
* 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();
}
}
这使您可以拨打RealmManager.getRealm()
的UI线程,它的生命周期被保留碎片管理。
在不启动后台线程的服务中使用RealmManager.getRealm()是否安全? – CuirMoustachu
嗯....考虑到Realm实例在我的情况下是关闭的,当活动关闭和服务超出活动时,我会投反对票。你应该在那里打开并关闭领域。 – EpicPandaForce
好吧,这证实了我的想法,我也想知道是否在每种情况下调用onDestroy,并且在那里减少领域实例数是否安全? – CuirMoustachu
我个人会考虑将它们移动到片段的onCreate/onDestroy上 – EpicPandaForce
尽管**实际上**我为UI线程保留一个Realm实例并使用保留的片段进行管理,但这有点棘手:D它可以避免所有这些棘手的生命周期shenanigan – EpicPandaForce
您是否有解决方案的样本? – CuirMoustachu