Лучшие практики для запроса базы данных 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и закройте его в ListFragment onDestroy как в примере кода ниже

    @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

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

Другие вопросы по тегам