代码之家  ›  专栏  ›  技术社区  ›  propoLis

如何为ui线程同时创建不同的领域实例?

  •  0
  • propoLis  · 技术社区  · 7 年前

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

    我读了太多关于realm性能改进、适配器管理和realm使用的文章。我在resume中打开领域,在pause中关闭它。但有时我的领域适配器显示为空。 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 :需要注意的是,领域实例是线程单例,这意味着静态构造函数将返回同一实例以响应来自给定线程的所有调用。

    我可以为领域线程管理领域,但不能管理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;
            }
    

    管理器:

    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 回复  |  直到 7 年前
        1
  •  1
  •   EpicPandaForce Jigar Joshi    7 年前

    你的问题的答案是 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() onCreateView / onDestroyView 管理生命周期,同时使用 realmManager.getLocalInstance() 在给定线程的其他位置。


    但可能更容易使用 findAllManaged* 在我的图书馆里 Monarchy 它处理自动领域生命周期管理。

    推荐文章