44

我在我的项目中使用 Android 兼容性库。我已经按照 DevGuide ( http://developer.android.com/reference/android/app/Fragment.html )中的描述设置了 ListFragment ,并使用了一个简单的 CursorLoader Christian 在没有内容提供者的情况下使用 ( CursorLoader 使用没有 ContentProvider)。

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

所以在我的应用程序中,我有 TitlesFragment、DetailsFragment、FragmentLayoutActivity、DetailsLayoutActivity。

是最佳实践吗...

  • 在 ListFragment 中打开数据库并在 ListFragment 中onActivityCreated关闭它,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创建适配器和 setListAdapteronLoadFinished

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

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

4

1 回答 1

6

抱歉,还没有使用 CursorLoader 和 Fragment 的经验,但我已经体验过在不同线程和活动的并发访问上下文中使用 SQLiteOpenHelper。

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

我做了什么:

  • 将您的 SQLiteOpenHelper 定义为应用程序范围的单例,而不是您看起来的活动范围
  • 在您的应用程序 onCreate 中实例化 SQLiteOpenHelper 单个实例
  • 不要在任何活动 onDestroy 中释放 SQLiteOpenHelper 实例,因为当活动停止时,另一个活动可能仍需要打开数据库
  • 我猜 SQLiteOpenHelper 实例应该在应用程序 onTerminate 中被清除(不确定因为 onTerminate 实际上几乎从未调用过)
  • 我有 DBAdapter 对象,它使用 mySQLiteOpenHelper.getWritableDatabase() 获取 SQLiteDatabase 引用
  • 这些 DBAdapter 通常在活动 onCreate 中分配并在 onDestroy 中释放

至少这是可行的,在拥有数千名用户的应用程序中没有崩溃。欢迎提出改进建议:-)

于 2011-12-06T17:21:51.063 回答