Лучшие практики для запроса базы данных SQLite в ListFragment с CursorLoader?
Я использую библиотеку совместимости Android в своем проекте. Я настроил ListFragment, как описано в DevGuide ( http://developer.android.com/reference/android/app/Fragment.html), и с помощью простого CursorLoader Christian можно использовать без провайдера контента ( использование CursorLoader без ContentProvider).
Вопрос в том, где в моей деятельности ListFragment / parent я должен открыть базу данных, вернуть курсор, создать Adapter и setListAdapter?
Итак, в моем приложении есть TitlesFragment, DetailsFragment, FragmentLayoutActivity, DetailsLayoutActivity.
Это лучшая практика...
открыть базу данных в ListFragment's
onActivityCreated
и закройте его в ListFragmentonDestroy
как в примере кода ниже@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Open database playersDatabaseHelper = new PlayersDBAdapter(getActivity()); playersDatabaseHelper.open(); getLoaderManager().initLoader(0, null, this); ... } @Override public void onDestroy() { super.onDestroy(); if (playersDatabaseHelper != null) { playersDatabaseHelper.close(); } }
запросить базу данных и вернуть курсор в
onCreateLoader
и создайте адаптер и setListAdapter вonLoadFinished
как в примере кода ниже@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. return new MyCursorLoader(getActivity()) { @Override public Cursor loadInBackground() { playersCursor = playersDatabaseHelper.getAllPlayers(); return playersCursor; } }; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // Create an empty adapter we will use to display the loaded data. playersAdapter = new RowAdapter(getActivity(), playersCursor, R.layout.players_overview_row); // Allocate the adapter to the List displayed within this fragment. setListAdapter(playersAdapter); playersAdapter.swapCursor(cursor); // The list should now be shown. if (isResumed()) { setListShown(true); } else { setListShownNoAnimation(true); } }
Я на правильном пути или я должен перенести некоторые из них куда-нибудь? Спасибо за ваше время!
1 ответ
Извините, у меня пока нет опыта работы с CursorLoader и Fragment, но я уже сталкивался с использованием SQLiteOpenHelper в контексте одновременного доступа к различным потокам и действиям.
Я предполагаю, что PlayersDBAdapter внутренне использует класс SQLiteOpenHelper. но не ясно, что делают ваши методы open() и close()?
Что я сделал:
- определите ваш SQLiteOpenHelper как синглтон приложения, а не как активность, как вы это делаете
- создание экземпляра SQLiteOpenHelper в вашем приложении onCreate
- НЕ выпускайте экземпляр SQLiteOpenHelper в любом действии onDestroy, так как при прекращении действия другому может потребоваться открыть БД
- Я думаю, экземпляр SQLiteOpenHelper должен быть очищен в приложении onTerminate (не уверен, так как onTerminate на практике почти никогда не вызывается)
- У меня есть объект DBAdapter, который получает ссылку на SQLiteDatabase с mySQLiteOpenHelper.getWritableDatabase()
- эти DBAdapter обычно выделяются в действии onCreate и выпускаются в onDestroy
По крайней мере, это работает, никаких сбоев в приложении с несколькими тысячами пользователей. Предложения по улучшению приветствуются:-)