如何同时为 ui 线程创建不同的领域实例?
How can I create a different realm instance at the same time for ui thread?
我有多个片段在活动中。我在片段 onActivityCreate
方法中调用了 myAdapter。
我阅读了太多关于领域性能改进、适配器管理、领域使用的文章。我在简历中打开领域并暂停关闭它。但有时我的领域适配器显示 empty.When 我删除了 closeRealm
方法,我的适配器是 运行 正常。
我的错误是因为来自不同适配器的重叠 openRealm 和 closeRealm。
第一个适配器正在打开 -> openRealm--onCreate (time : 21:15) closing->closeRealm--onPause (time : 21:30:12)
第二个适配器正在打开 -> openRealm--onCreate (时间:21:30:23) :: 上面的适配器正在关闭这个领域
https://realm.io/docs/java/latest/#configuring-a-realm :重要的是要注意 Realm 实例是线程单例,这意味着静态构造函数将 return 相同的实例以响应来自给定线程的所有调用。
我可以管理领域线程的领域,但无法管理 ui 线程。如何同时为 ui 线程创建不同的领域实例?请帮助我。
Realm adapter:
abstract class MyRealmRecyclerViewAdapter<T extends MyModel, VH extends RecyclerView.ViewHolder>
extends RealmRecyclerViewAdapter<MyModel, VH> {
protected Context context;
private String TAG = MyRealmRecyclerViewAdapter.class.getSimpleName();
protected Realm realm;
MyRealmRecyclerViewAdapter(@Nullable OrderedRealmCollection<T> data, Realm realm) {
super((OrderedRealmCollection<MyModel>) data, true, true);
if (data != null && !data.isManaged()) {
throw new IllegalStateException("Only use this adapter with managed RealmCollection, " +
"for un-managed lists you can just use the BaseRecyclerViewAdapter");
}
setRealm(realm);
setHasStableIds(true);
}
}
My fragment:
public class MyFragment extends Fragment {
private boolean isRealmAssignee = false;
private Realm realm;
@Override
public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle);
Mylog.i(TAG, " onActivityCreated");
try {
myAdapter = new MyRealmRecyclerViewAdapter<>(this,
new MyQueries().getAllItems(getRealm()),getRealm());
recyclerView.setAdapter(myAdapter);
} catch (Exception e) {
Mylog.printStackTrace(TAG + " initializeListAdapter error", e);
}
}
@Override
public void onResume() {
super.onResume();
Mylog.i(TAG, " onResume");
setRealm();
}
@Override
public void onPause() {
super.onPause();
Mylog.i(TAG, " onPause");
closeRealm();
}
public void setRealm() {
if (!isRealmAssignee && !RealmManager.checkRealm(realm)) {
this.realm = RealmManager.open();
isRealmAssignee = true;
}
}
public Realm getRealm() {
if (!RealmManager.checkRealm(realm)) {
isRealmAssignee = false;
setRealm();
}
return realm;
}
public void closeRealm() {
RealmManager.close(realm);
isRealmAssignee = false;
}
RealmManager:
public class RealmManager {
public synchronized static Realm open() {
return Realm.getDefaultInstance();
}
public synchronized static void close(Realm mRealm) {
if (checkRealm(mRealm)) {
mRealm.close();
}
}
public static boolean checkRealm(Realm realm) {
return realm != null && !realm.isClosed();
}
}
您问题的答案是使用 ThreadLocal<Realm>
.
private final ThreadLocal<Realm> localRealms = new ThreadLocal<>();
/**
* Opens a reference-counted local Realm instance.
*
* @return the open Realm instance
*/
public Realm openLocalInstance() {
checkDefaultConfiguration();
Realm realm = Realm.getDefaultInstance(); // <-- this could use input RealmConfiguration
Realm localRealm = localRealms.get();
if(localRealm == null || localRealm.isClosed()) {
localRealms.set(realm);
}
return realm;
}
public Realm getLocalInstance() {
Realm realm = localRealms.get();
if(realm == null || realm.isClosed()) {
throw new IllegalStateException(
"No open Realms were found on this thread.");
}
return realm;
}
public void closeLocalInstance() {
checkDefaultConfiguration();
Realm realm = localRealms.get();
if(realm == null || realm.isClosed()) {
throw new IllegalStateException(
"Cannot close a Realm that is not open.");
}
realm.close();
// noinspection ConstantConditions
if(Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()) <= 0) {
localRealms.set(null);
}
}
然后您可以使用 onCreateView
/onDestroyView
中的 realmManager.openLocalInstance()
和 realmManager.closeLocalInstance()
来管理生命周期,同时在给定线程的其他地方使用 realmManager.getLocalInstance()
.
但在我名为 Monarchy 的库中使用 findAllManaged*
可能更容易,它处理自动领域生命周期管理。
我有多个片段在活动中。我在片段 onActivityCreate
方法中调用了 myAdapter。
我阅读了太多关于领域性能改进、适配器管理、领域使用的文章。我在简历中打开领域并暂停关闭它。但有时我的领域适配器显示 empty.When 我删除了 closeRealm
方法,我的适配器是 运行 正常。
我的错误是因为来自不同适配器的重叠 openRealm 和 closeRealm。
第一个适配器正在打开 -> openRealm--onCreate (time : 21:15) closing->closeRealm--onPause (time : 21:30:12)
第二个适配器正在打开 -> openRealm--onCreate (时间:21:30:23) :: 上面的适配器正在关闭这个领域
https://realm.io/docs/java/latest/#configuring-a-realm :重要的是要注意 Realm 实例是线程单例,这意味着静态构造函数将 return 相同的实例以响应来自给定线程的所有调用。
我可以管理领域线程的领域,但无法管理 ui 线程。如何同时为 ui 线程创建不同的领域实例?请帮助我。
Realm adapter:
abstract class MyRealmRecyclerViewAdapter<T extends MyModel, VH extends RecyclerView.ViewHolder>
extends RealmRecyclerViewAdapter<MyModel, VH> {
protected Context context;
private String TAG = MyRealmRecyclerViewAdapter.class.getSimpleName();
protected Realm realm;
MyRealmRecyclerViewAdapter(@Nullable OrderedRealmCollection<T> data, Realm realm) {
super((OrderedRealmCollection<MyModel>) data, true, true);
if (data != null && !data.isManaged()) {
throw new IllegalStateException("Only use this adapter with managed RealmCollection, " +
"for un-managed lists you can just use the BaseRecyclerViewAdapter");
}
setRealm(realm);
setHasStableIds(true);
}
}
My fragment:
public class MyFragment extends Fragment {
private boolean isRealmAssignee = false;
private Realm realm;
@Override
public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle);
Mylog.i(TAG, " onActivityCreated");
try {
myAdapter = new MyRealmRecyclerViewAdapter<>(this,
new MyQueries().getAllItems(getRealm()),getRealm());
recyclerView.setAdapter(myAdapter);
} catch (Exception e) {
Mylog.printStackTrace(TAG + " initializeListAdapter error", e);
}
}
@Override
public void onResume() {
super.onResume();
Mylog.i(TAG, " onResume");
setRealm();
}
@Override
public void onPause() {
super.onPause();
Mylog.i(TAG, " onPause");
closeRealm();
}
public void setRealm() {
if (!isRealmAssignee && !RealmManager.checkRealm(realm)) {
this.realm = RealmManager.open();
isRealmAssignee = true;
}
}
public Realm getRealm() {
if (!RealmManager.checkRealm(realm)) {
isRealmAssignee = false;
setRealm();
}
return realm;
}
public void closeRealm() {
RealmManager.close(realm);
isRealmAssignee = false;
}
RealmManager:
public class RealmManager {
public synchronized static Realm open() {
return Realm.getDefaultInstance();
}
public synchronized static void close(Realm mRealm) {
if (checkRealm(mRealm)) {
mRealm.close();
}
}
public static boolean checkRealm(Realm realm) {
return realm != null && !realm.isClosed();
}
}
您问题的答案是使用 ThreadLocal<Realm>
.
private final ThreadLocal<Realm> localRealms = new ThreadLocal<>();
/**
* Opens a reference-counted local Realm instance.
*
* @return the open Realm instance
*/
public Realm openLocalInstance() {
checkDefaultConfiguration();
Realm realm = Realm.getDefaultInstance(); // <-- this could use input RealmConfiguration
Realm localRealm = localRealms.get();
if(localRealm == null || localRealm.isClosed()) {
localRealms.set(realm);
}
return realm;
}
public Realm getLocalInstance() {
Realm realm = localRealms.get();
if(realm == null || realm.isClosed()) {
throw new IllegalStateException(
"No open Realms were found on this thread.");
}
return realm;
}
public void closeLocalInstance() {
checkDefaultConfiguration();
Realm realm = localRealms.get();
if(realm == null || realm.isClosed()) {
throw new IllegalStateException(
"Cannot close a Realm that is not open.");
}
realm.close();
// noinspection ConstantConditions
if(Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()) <= 0) {
localRealms.set(null);
}
}
然后您可以使用 onCreateView
/onDestroyView
中的 realmManager.openLocalInstance()
和 realmManager.closeLocalInstance()
来管理生命周期,同时在给定线程的其他地方使用 realmManager.getLocalInstance()
.
但在我名为 Monarchy 的库中使用 findAllManaged*
可能更容易,它处理自动领域生命周期管理。