简体   繁体   English

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

[英]How can I create a different realm instance at the same time for ui thread?

I have multiple fragments which are inside activities. 我有多个内部活动片段。 I have called myAdapter in fragment onActivityCreate method. 我在片段onActivityCreate方法中调用了myAdapter。

I have read too many articles for realm performance improvements, adapter management, realm usage. 我阅读了太多有关领域性能改进,适配器管理和领域用法的文章。 I open the realm in resume and close it in pause. 我在简历中打开该领域,并在暂停中将其关闭。 But sometimes my realm adapter has shown empty.When I've deleted closeRealm method, my adapter was running normally. 但是有时候我的领域适配器显示为空。当我删除closeRealm方法时,我的适配器运行正常。

My error is because of overlapping openRealm and closeRealm from different adapters. 我的错误是由于来自不同适配器的openRealm和closeRealm重叠。

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

Second adapter is opening -> openRealm--onCreate (time: 21:30:23) :: Above adapter is closing this realm 第二个适配器正在打开-> openRealm--onCreate (时间:21:30:23) ::上面的适配器正在关闭该领域

https://realm.io/docs/java/latest/#configuring-a-realm : It is important to note that Realm instances are thread singletons, meaning that the static constructor will return the same instance in response to all calls from a given thread. https://realm.io/docs/java/latest/#configuring-a-realm :重要的是要注意,Realm实例是线程单例,这意味着静态构造函数将响应来自a的所有调用返回相同的实例。给定线程。

I can manage realm for realm thread but can't manage ui thread. 我可以为领域线程管理领域,但不能管理ui线程。 How can I create a different realm instance at the same time for ui thread? 如何同时为ui线程创建其他领域实例? Please help me. 请帮我。

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

The answer to your question would be to use a ThreadLocal<Realm> . 您问题的答案将是使用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);
    }
}

And then you could use realmManager.openLocalInstance() and realmManager.closeLocalInstance() from onCreateView / onDestroyView to manage the lifecycle, while use realmManager.getLocalInstance() elsewhere on the given thread. 然后,您可以使用onCreateView / onDestroyView realmManager.openLocalInstance()realmManager.closeLocalInstance()来管理生命周期,而在给定线程的其他位置使用realmManager.getLocalInstance()


But it might just be easier to use findAllManaged* in my library named Monarchy which handles automatic Realm lifecycle management. 但是,在我的名为Monarchy的库中使用findAllManaged*可能会更容易,该库可以处理自动Realm生命周期管理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM