使用CursorLoader在ListFragment数据库中查询SQLite的最佳实践?

时间:2021-11-15 20:03:19

I'm using Android Compatibility Library in my project. I've set up ListFragment as described in the DevGuide (http://developer.android.com/reference/android/app/Fragment.html), and using a simple CursorLoader Christian made be used without content provider (CursorLoader usage without ContentProvider).

我在我的项目中使用Android兼容性库。我已经按照DevGuide (http://developer.android.com/reference/android/app/Fragment.html)中描述的那样设置了ListFragment,并使用一个简单的CursorLoader Christian,使其不使用内容提供程序(CursorLoader使用而不使用内容提供程序)。

The question is where, in my ListFragment / parent Activity, should I open database, return the Cursor, create Adapter and setListAdapter?

问题是,在我的ListFragment / parent活动中,我应该在哪里打开数据库,返回光标,创建适配器和setListAdapter?

So in my app, I have TitlesFragment, DetailsFragment, FragmentLayoutActivity, DetailsLayoutActivity.

在我的应用中,我有TitlesFragment fragment fragment片段,FragmentLayoutActivity, DetailsLayoutActivity。

Is the best practice...

练习是最好的……

  • to open database in ListFragment's onActivityCreatedand close it in ListFragment's onDestroy like in code sample below

    打开ListFragment’s onactivitycreated并关闭ListFragment’s 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();
        }
    }
    
  • query database and return the cursor in onCreateLoader, and create the Adapter and setListAdapter in onLoadFinished like in code sample below

    查询数据库并在onCreateLoader中返回光标,并在onLoadFinished中创建适配器和setListAdapter,如下面的代码示例所示

    @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);
        }
    }
    

Am I on the right track or should I move some of those somewhere? Thanks for your time!

我是在正确的轨道上还是应该把其中的一些移到别的地方?谢谢你的时间!

1 个解决方案

#1


6  

Sorry no experience in CursorLoader yet and Fragment, but I already experienced use of SQLiteOpenHelper in the context of concurrent access by different threads & activities.

对不起,我还没有使用CursorLoader和Fragment,但是我已经在使用SQLiteOpenHelper时遇到过不同线程和活动并发访问的情况。

I will assume that PlayersDBAdapter is internally using a SQLiteOpenHelper class. but it is not clear what your methods open() and close() are doing?

我将假设PlayersDBAdapter在内部使用SQLiteOpenHelper类。但是不清楚open()和close()方法在做什么?

What I did:

我所做的:

  • define your SQLiteOpenHelper as an application wide singleton, not activity wide as you seem to do
  • 将您的SQLiteOpenHelper定义为应用程序范围的单例,而不是像您看起来那样的活动范围
  • instantiate SQLiteOpenHelper single instance in your Application onCreate
  • 在您的应用程序中实例化SQLiteOpenHelper单个实例。
  • DON'T release SQLiteOpenHelper instance in any activity onDestroy, as when an activity stops, another one might still have to open the DB
  • 不要在任何活动中释放SQLiteOpenHelper实例,因为当活动停止时,另一个活动可能仍然需要打开DB。
  • I guess SQLiteOpenHelper instance should be cleared in application onTerminate (not sure as onTerminate is in practice almost never called)
  • 我想SQLiteOpenHelper应该在onTerminate应用程序中清除(不确定onTerminate在实践中几乎从未调用过)
  • I have DBAdapter object which gets a SQLiteDatabase reference with mySQLiteOpenHelper.getWritableDatabase()
  • 我有一个DBAdapter对象,它通过mySQLiteOpenHelper.getWritableDatabase()获得一个SQLiteDatabase引用
  • these DBAdapter are typically allocated in activity onCreate and released in onDestroy
  • 这些DBAdapter通常在活动onCreate中分配,并在onDestroy中释放

At least this works, no crashs in an application with several thousands users. Suggestions to improve that are welcome :-)

至少这是可行的,在一个拥有数千用户的应用程序中没有碰撞。建议改善,欢迎:

#1


6  

Sorry no experience in CursorLoader yet and Fragment, but I already experienced use of SQLiteOpenHelper in the context of concurrent access by different threads & activities.

对不起,我还没有使用CursorLoader和Fragment,但是我已经在使用SQLiteOpenHelper时遇到过不同线程和活动并发访问的情况。

I will assume that PlayersDBAdapter is internally using a SQLiteOpenHelper class. but it is not clear what your methods open() and close() are doing?

我将假设PlayersDBAdapter在内部使用SQLiteOpenHelper类。但是不清楚open()和close()方法在做什么?

What I did:

我所做的:

  • define your SQLiteOpenHelper as an application wide singleton, not activity wide as you seem to do
  • 将您的SQLiteOpenHelper定义为应用程序范围的单例,而不是像您看起来那样的活动范围
  • instantiate SQLiteOpenHelper single instance in your Application onCreate
  • 在您的应用程序中实例化SQLiteOpenHelper单个实例。
  • DON'T release SQLiteOpenHelper instance in any activity onDestroy, as when an activity stops, another one might still have to open the DB
  • 不要在任何活动中释放SQLiteOpenHelper实例,因为当活动停止时,另一个活动可能仍然需要打开DB。
  • I guess SQLiteOpenHelper instance should be cleared in application onTerminate (not sure as onTerminate is in practice almost never called)
  • 我想SQLiteOpenHelper应该在onTerminate应用程序中清除(不确定onTerminate在实践中几乎从未调用过)
  • I have DBAdapter object which gets a SQLiteDatabase reference with mySQLiteOpenHelper.getWritableDatabase()
  • 我有一个DBAdapter对象,它通过mySQLiteOpenHelper.getWritableDatabase()获得一个SQLiteDatabase引用
  • these DBAdapter are typically allocated in activity onCreate and released in onDestroy
  • 这些DBAdapter通常在活动onCreate中分配,并在onDestroy中释放

At least this works, no crashs in an application with several thousands users. Suggestions to improve that are welcome :-)

至少这是可行的,在一个拥有数千用户的应用程序中没有碰撞。建议改善,欢迎: