如何同时为 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* 可能更容易,它处理自动领域生命周期管理。