关闭不同文件的领域

时间:2017-03-02 12:02:34

标签: java android realm

我是一个Android项目的新手,不幸的是,旧团队已经离开了,而我却一无所知。

项目结构如下

活动,片段,领域(包含crud文件和DAO文件)

mainActivity:

        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.menu_drawer_activity);
                ButterKnife.bind(this);
                EventBus.getDefault().register(this);
                setSupportActionBar(toolbar);
                String ChannelId = UAirship.shared().getPushManager().getChannelId();

                Realm.init(this);
                RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().schemaVersion(2).deleteRealmIfMigrationNeeded().build();
                Realm.setDefaultConfiguration(realmConfiguration); // Make this Realm the default
                realm = Realm.getInstance(realmConfiguration);

                showInitalFragment();
                setUserInfoInNaviagtionDrawer();
                setupUI();
            }

// some logic

      @Override
        protected void onDestroy() {
            EventBus.getDefault().unregister(this);
            realm.close();
            super.onDestroy();
        }

现在在crud文件中并且发生了这种情况:

CRUDfile1.java:http://ideone.com/fs0RYo

DAOfile1.java:http://ideone.com/1klhW8

现在的问题是,有一个lof ot领域实例已经创建并保持打开大量内存,有时会导致应用程序崩溃,我无法关闭它们(应用程序将崩溃因此评论)。任何想法我该如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

更改两个类中的所有方法
{
    Realm realm = RealmObject.getRealmObject(MyApplication.getAppContext());
    <your-code>
}

to(如果你的minSdkVersion&gt; = 19)

{
    try(Realm realm = RealmObject.getRealmObject(MyApplication.getAppContext())) {
        <your-code>
    }
}

{
    Realm realm = RealmObject.getRealmObject(MyApplication.getAppContext()));
    try {
        <your-code>
    } catch (Exception e) {
        realm.cancelTransaction();
    } finally {
        if (realm != null) {
            realm.close();
        }
    }
}

因此,您将关闭所有领域实例。

答案 1 :(得分:0)

  

现在的问题是有一个lof ot领域实例已经创建并保持打开大量内存,有时会导致应用程序崩溃,我无法关闭它们(应用程序将崩溃因此评论)。任何想法我该如何解决这个问题?

Realm实例是引用计数,意味着在给定的线程上,实际上只有一个打开的实例。但是只有在所有&#34;本地Realm实例&#34;已关闭。

例如,

Realm realm = Realm.getDefaultInstance();
Realm realm2 = Realm.getDefaultInstance();

realm2.close();
realm.close(); // <-- this is when Realm is released for the given thread

实际上,它们都指向相同的&#34;底层Realm&#34;,即使它们被视为两个不同的&#34;本地Realm实例&#34;。

因为&#34;打开太多&#34;所以你不会因为内存不足而耗尽。

但是,如果您在非looper后台线程上打开Realm实例并且不关闭它们,则可能内存不足并崩溃

因此,在后台线程中,您应该看到以下设置:

try(Realm realm = Realm.getDefaultInstance()) {
     // do things here
} // auto-close

Realm realm = null;
try {
    realm = Realm.getDefaultInstance();
    realm.executeTransaction(new Realm.Transaction() {
       // ... actual transaction code here
    });
} finally {
    if(realm != null) {
        realm.close();
    }
}

整个RealmObject.getRealmObject(Context)事情看起来完全错误。

我已经看到人们这样做了,Realm.getDefaultInstance().where(...)这例如创建了一个你永远无法关闭的实例,你应该关闭它们。

答案 2 :(得分:-1)

最佳做法是保持所有方法在单个类中执行特定类型的操作,以便轻松维护并保持文件结构整洁干净:

仅在此控制器类中的单个控制器类和realm实例中添加领域查询:

    public class RealmController {

    private static RealmController instance;
    private final Realm realm;

    public RealmController(Application application) {
        realm = Realm.getDefaultInstance();
    }

    public static RealmController with(Fragment fragment) {

        if (instance == null) {
            instance = new RealmController(fragment.getActivity().getApplication());
        }
        return instance;
    }

    public static RealmController with(Activity activity) {

        if (instance == null) {
            instance = new RealmController(activity.getApplication());
        }
        return instance;
    }

    public static RealmController with(Application application) {

        if (instance == null) {
            instance = new RealmController(application);
        }
        return instance;
    }

    public static RealmController getInstance() {

        return instance;
    }

    public Realm getRealm() {

        return realm;
    }

    //Refresh the realm istance
    public void refresh() {

        realm.refresh();
    }

    //clear all objects from Book.class
    public void clearAll() {

        realm.beginTransaction();
        realm.clear(Book.class);
        realm.commitTransaction();
    }

    //find all objects in the Book.class
    public RealmResults<Book> getBooks() {

        return realm.where(Book.class).findAll();
    }

    //query a single item with the given id
    public Book getBook(String id) {

        return realm.where(Book.class).equalTo("id", id).findFirst();
    }

    //check if Book.class is empty
    public boolean hasBooks() {

        return !realm.allObjects(Book.class).isEmpty();
    }

    //query example
    public RealmResults<Book> queryedBooks() {

        return realm.where(Book.class)
                .contains("author", "Author 0")
                .or()
                .contains("title", "Realm")
                .findAll();

    }
}

现在,当线程更改或片段/活动破坏时,创建一个方法来关闭此控制器类的realm实例:

 public void closeRealmInstance(){
    if(realm != null){
    realm.close();
    }
}

现在,你很高兴去。访问领域如下面的片段:

RealmController realmController = new RealmController(yourContext);
BookClass bookObj = realmController.getBook();
realmController.closeRealmInstance();

使用上述结构,您将简化代码,您将更好地了解现有代码中发生的情况。享受编码!!!如果它有帮助,请进行投票。