2017-02-19 13 views
1

У меня есть Android приложение, которое использует довольно общий шаблон дизайна:Лучшая практика для открытия/закрытия экземпляров Realm

  1. Основным видом деятельности, по существу, представляющий собой список объектов - на небольших устройствах, он делает это хостингов один фрагмент, который отображает пересмотр этого списка. На более крупных устройствах он содержит два фрагмента, один из которых имеет одинаковое перераспределение объектов, а другой, который будет размещать детали для отдельных объектов, когда один из них выбран в списке.
  2. На небольших устройствах, когда сделан выбор из списка, запускается действие, в котором размещается фрагмент, который использует ViewPager, чтобы позволить «прокручивать» по списку объектов и редактировать каждый из них на месте.

В обоих случаях пользователю разрешается редактировать только фрагмент детали.

я в настоящее время у меня экземпляр области инициализируется в классе приложения, то экземпляр по умолчанию извлекается в деятельности базового класса я использую, чтобы держать некоторые методы домашнего хозяйства:

public abstract class SingleFragmentActivity extends AppCompatActivity { 
    private Realm realm; 
    protected abstract Fragment createFragment(); 

    @LayoutRes 
    protected int getLayoutResId() { 
     return R.layout.activity_fragment; 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     realm = Realm.getDefaultInstance(); 
     // Initialize ProfileLab 
     ProfileLab.get(realm); 
     setContentView(getLayoutResId()); 

     FragmentManager fm = getSupportFragmentManager(); 
     Fragment fragment = fm.findFragmentById(R.id.fragment_container); 

     if (fragment == null) { 
      fragment = createFragment(); 
      fm.beginTransaction() 
        .add(R.id.fragment_container, fragment) 
        .commit(); 
     } 
    } 

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

Обратите внимание, что я храню этот экземпляр области в статическом классе «ProfileLab»:

// Initialize ProfileLab 
ProfileLab.get(realm); 

Тогда в различных фрагментах, обновляющих данные, я делаю такие вещи, как:

mProfile = ProfileLab.get().getProfile(profileId); 
* 
* do CRUD activities here for example: 
* 
    private void deleteProfile() { 
     ProfileLab.get().deleteProfile(mProfile); 
     mCallbacks.onProfileUpdated(mProfile); 
    } 

Тогда в ProfileLab, это выглядит следующим образом:

общественного логический deleteProfile (профиль с) { булевой RetVal = истина;

try { 
    mRealm.beginTransaction(); 
    c.deleteFromRealm(); 

} catch (Exception e) { 
    retVal = false; 
} finally { 
    if (mRealm != null) { 
     if (retVal) { 
      mRealm.commitTransaction(); 
     } else { 
      mRealm.cancelTransaction(); 
     } 

    } 
} 
return (retVal); 

}

Мой вопрос - это проблема, по существу, считают, что экземпляр Realm открыть как, что на протяжении использования приложения? Я заметил этот пункт в документации:

Если вы получаете экземпляр Realm из потока, который не имеет Looper прилагается, то объекты из такого экземпляра не будет обновляться, если метод waitForChange() не вызывается , Важно отметить, что , требующий хранения старой версии ваших данных, является дорогостоящим с точки зрения объема памяти и дискового пространства, а стоимость увеличивается с числом версий между сохраненным и последним. Вот почему важно закрыть экземпляр Realm, как только вы закончите с его в потоке.

Дело в том, что я не «сделал это», потому что это в потоке пользовательского интерфейса, который, очевидно, работает на протяжении всего моего приложения.

Я не могу открыть/закрыть экземпляр области только для атомных обновлений, потому что мне нужно использовать результат первоначального запроса, чтобы показать список объектов, из которых можно выбрать редактирование, - когда я попытался это изначально (У меня был объект realm open/close внутри каждого метода в ProfileLab). Я получил ошибку в адаптерах recycler, которые были закрыты.

В примере кода, показывающего использование вида ресайклера, отображается область, извлекаемая/используемая/закрытая на уровне отдельной активности, если я делаю это между двумя простыми действиями (размещением RecyclerView и размещением ViewPager), будут ли данные обновления отражаются друг в друге?

+0

Если я использую несколько видов деятельности, которые довольно редко, то я эталон подсчитывает количество открытых мероприятий, и закройте Realm, если число достигает 0 (см [пример] (https://github.com/ Zhuinden/realm-book-example)) – EpicPandaForce

+0

Благодарим вас за отзыв, я просмотрю ваш пример. – tfrysinger

ответ

0

Realm автоматически сохранит Realms в потоках Looper в актуальном состоянии. Эта конкретная строка в документации в основном относится к фоновым потокам. Таким образом, ваш код в порядке, даже если onDestroy не может быть вызван.

Вы также можете прочитать эти соответствующие разделы в документации:

https://realm.io/docs/java/latest/#closing-realm-instances https://realm.io/docs/java/latest/#controlling-the-lifecycle-of-realm-instances

0

Открытие и закрытие область внутри TRY/поймать блок рекомендуется. например:

Это простой пример при использовании. Если вы можете закрыть в пределах AsyncTask,, это будет лучше.

official documentation относится, что если вы используете minSdkVersion> = 19 и Java> = 7, вы не будете закрывать его вручную.

try (Realm realm = Realm.getDefaultInstance()) { 
// No need to close the Realm instance manually 
}