Лучшие практики для запроса базы данных SQLite в ListFragment с CursorLoader? - PullRequest
44 голосов
/ 28 сентября 2011

Я использую библиотеку совместимости Android в своем проекте.Я настроил ListFragment, как описано в DevGuide (http://developer.android.com/reference/android/app/Fragment.html),, и использую простой CursorLoader Christian, предназначенный для использования без провайдера контента ( Использование CursorLoader без ContentProvider ).

Вопрос в том, , где в моем ListFragment / parent Activity мне нужно открыть базу данных, вернуть курсор, создать Adapter и setListAdapter?

Так что в моем приложении есть TitlesFragment, DetailsFragment, FragmentLayoutActivity,DetailsLayoutActivity.

Лучше всего ...

  • , чтобы открыть базу данных в onActivityCreated ListFragment и закрыть ее в onDestroy ListFragment, как в примере кода ниже

    @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, и создайте Adapter и 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 Ответ

6 голосов
/ 06 декабря 2011

Извините, у меня пока нет опыта работы с CursorLoader и Fragment, но я уже сталкивался с использованием SQLiteOpenHelper в контексте одновременного доступа к различным потокам и действиям.

Я предполагаю, что PlayersDBAdapter внутренне использует класс SQLiteOpenHelper.но неясно, что делают ваши методы open () и close ()?

Что я сделал:

  • определяем ваш SQLiteOpenHelper как приложение * шириной 1009 *синглтон, а не широкая активность, как вы, похоже,
  • создаете экземпляр одного экземпляра SQLiteOpenHelper в вашем приложении onCreate
  • НЕ выпускайте экземпляр SQLiteOpenHelper в любом действии onDestroy, так как при прекращении действия другое действие можетвсе еще нужно открыть DB
  • Я думаю, экземпляр SQLiteOpenHelper должен быть очищен в приложении onTerminate (не уверен, поскольку onTerminate на практике почти никогда не вызывается)
  • У меня есть объект DBAdapter, который получает ссылку на SQLiteDatabase сmySQLiteOpenHelper.getWritableDatabase ()
  • эти DBAdapter обычно выделяются в действии onCreate и выпускаются в onDestroy

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...