如何访问由不同Realm实例创建的托管对象?

时间:2018-02-18 12:00:27

标签: android realm

我在Android中创建了一个使用领域的应用程序。

我有一个启动画面,可以加载操作所需的所有数据,还有许多使用该数据的活动。

该数据作为静态变量存储在Application类扩展中。

我的问题是,当我尝试操纵其他活动中的数据时,我收到有关关闭领域数据库的错误。

我通过在Application上创建对数据库的静态引用来解决这个问题。在OnCreate()中打开并在OnTerminate()中关闭它,但我觉得这是错误的。

我还通过创建非托管对象(即使用copyFromRealm从Realm中检索它们)解决了这个问题,然后当我需要进行修改时将它们复制回我刚创建的领域实例。

解决此问题的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

  

我有一个启动画面,可以加载操作所需的所有数据,还有许多使用该数据的活动。

     

该数据作为静态变量存储在Application类扩展中。

非常非常有趣 - 您是否尝试将应用程序放在屏幕后台,然后转到Android Studio的 Logcat 标签,转到左下角的其他菜单项,然后单击TERMINATE?

terminate button

有趣的是,如果您的应用程序在后台执行此操作,然后从启动器重新打开应用程序,您将获得与通过低内存杀死应用程序完全相同的效果条件。

在你的情况下,你几乎可以在任何不是闪屏的屏幕上与NPE崩溃!非常非常有趣。

(另外,Application.onTerminate()永远不会被调用。所以这也没有帮助。)

无论如何,要回到原来的问题,

  

我的问题是,当我尝试操纵其他活动中的数据时,我收到有关关闭领域数据库的错误。

     

解决此问题的正确方法是什么?

官方文档的Best Practices: Controlling the lifecycle of Realm instances部分在这方面非常有帮助。

public class MyActivity extends Activity {
    private Realm realm;
    private RealmResults<Dog> dogs;
    private RealmChangeListener<RealmResults<Dog>> realmChangeListener = (results) -> {
         // do something on first load + future changes of Dogs
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        realm = Realm.getDefaultInstance();

        setContentView(R.layout.activity_main);
        dogs = realm.where(Dog.class).sort("age").findAllAsync();
        dogs.addChangeListener(realmChangeListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        dogs.removeAllChangeListeners();
        dogs = null;
        realm.close();
        realm = null;
    }
}

public class MyFragment extends Fragment {
    private Realm realm;
    private RealmResults<Dog> dogs;
    private RealmChangeListener<RealmResults<Dog>> realmChangeListener = (results) -> {
         // do something on first load + future changes of Dogs
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        realm = Realm.getDefaultInstance();

        View root = inflater.inflate(R.layout.fragment_view, container, false);

        return root;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        dogs = realm.where(Dog.class).sort("age").findAllAsync();
        dogs.addChangeListener(realmChangeListener);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        dogs.removeAllChangeListeners();
        dogs = null;
        realm.close();
        realm = null;
    }
}

Realm实例在给定的thraead上被重新计数,所以我猜答案是,#34;在你需要的时候保持一个打开&#34;。当然,当你不再做的时候关闭它。