如何同时为ui线程创建其他领域实例?

时间:2018-07-13 13:50:40

标签: android realm realm-list realmrecyclerviewadapter

我有多个活动片段。我在片段onActivityCreate方法中调用了myAdapter。

我阅读了太多有关领域性能改进,适配器管理和领域使用的文章。我在简历中打开该领域,并在暂停中将其关闭。但是有时我的领域适配器显示为空。删除closeRealm方法后,我的适配器运行正常。

我的错误是由于来自不同适配器的openRealm和closeRealm重叠。

第一个适配器打开-> openRealm--onCreate (时间:21:15)关闭-> closeRealm--onPause (时间:21:30:12)

第二个适配器正在打开-> openRealm--onCreate (时间:21:30:23) ::上面的适配器正在关闭该领域

https://realm.io/docs/java/latest/#configuring-a-realm:重要的是要注意,Realm实例是线程单例,这意味着静态构造函数将响应来自给定线程的所有调用而返回相同的实例。

我可以管理领域线程的领域,但不能管理ui线程。如何同时为ui线程创建其他领域实例?请帮助我。

  

领域适配器:

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);
    }

}
  

我的片段:

    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();
    }
}

1 个答案:

答案 0 :(得分:1)

您的问题的答案是使用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);
    }
}

然后,您可以使用realmManager.openLocalInstance() / realmManager.closeLocalInstance()中的onCreateViewonDestroyView来管理生命周期,而在给定线程的其他地方使用realmManager.getLocalInstance()。 / p>


但是在我的名为Monarchy的库中使用findAllManaged*可能会更容易,该库可以处理自动Realm生命周期管理。