【问题标题】:How to correctly handle database in ListFragment?如何正确处理 ListFragment 中的数据库?
【发布时间】:2016-08-23 07:26:41
【问题描述】:

我正在构建一个非常简单的应用程序,其中包含一个 SQLiteDatabase,我想使用自定义 SimpleCursorAdapter 将其显示在 ListFragment 中。

我的代码运行良好,但我不确定我是否以正确的方式做事。我已经搜索了很多(权威)示例,但只找到了使用ArrayAdapter 的过于简化的示例,或者使用ContentProvider 的过于复杂的示例。

 

列表片段

public class CallListFragment extends ListFragment{

    private CallListDbHelper dbHelper;
    private SQLiteDatabase db;
    private Cursor cursor;
    private CallListAdapter adapter;



    @Override
    public void onResume() {
        super.onResume();

        // Create a database helper
        dbHelper = new CallListDbHelper(getActivity());

        // Get the database
        db = dbHelper.getReadableDatabase();

        // Get a cursor to the entire call list from the database
        cursor = db.query(                                                          // SELECT
                CallEntry.TABLE_NAME,                                               // FROM ...
                new String[] {                                                      // <columns>
                        CallEntry._ID,
                        CallEntry.COLUMN_NUMBER,
                        CallEntry.COLUMN_TIME },
                null,                                                               // WHERE ... (x = ?, y = ?)
                null,                                                               //   <columnX, columnY>
                null,                                                               // GROUP BY ...
                null,                                                               // HAVING ...
                CallEntry.COLUMN_TIME + " DESC"                                     // ORDER BY ...
        );

        adapter = new CallListAdapter(getActivity(), cursor);
        setListAdapter(adapter);
    }


    @Override
    public void onPause() {
        super.onPause();

        // Close cursor, database and helper
        if( null !=cursor ) cursor.close();
        if( null != db ) db.close();
        if( null != dbHelper ) dbHelper.close();
    }

}

 

适配器

public class CallListAdapter extends SimpleCursorAdapter {


    private static final String[] FROM = {
        CallListContract.CallEntry.COLUMN_NUMBER,
        CallListContract.CallEntry.COLUMN_TIME
    };

    private static final int[] TO = {
        R.id.phoneNumber,
        R.id.time
    };



    public CallListAdapter(Context context, Cursor cursor){
        this(context, R.layout.listitem_call, cursor, FROM, TO);
    }


    private CallListAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to) {
        super(context, layout, cursor, from, to, 0);
    }

}

【问题讨论】:

  • 嗯,片段看起来不错。 CallListAdapter 可能也很有趣。
  • 已添加适配器代码。

标签: android android-listfragment android-cursoradapter android-cursor android-database


【解决方案1】:

对于一些简单的事情,它会起作用。但是……

你在一个地方使用你的数据库吗?

你的数据库有多大?

您多久点击一次 onResume/onPause?

一般建议 onResume/onPause 应该尽可能快,但是 DB 操作可能会阻塞...

特别是第一次接触(创建)数据库可能会很耗时,您可能会得到ANR

不要将 Activity 用作上下文,否则可能会导致内存泄漏。推荐的方法是将应用程序的上下文与singleton pattern 结合使用,这样您就不会打扰to close DB

CursorLoader 需要打开光标才能运行,并会为您调用光标上的 close()。至于 SimpleCursorAdapter 我在源代码中没有看到自动关闭功能 =(.

【讨论】:

  • 也许是一些示例代码来阐明你的意思......?
  • 我的印象是CursorLoader 需要ContentProvider,这对于我正在做的事情来说似乎太过分了。他们甚至在Creating a Content Provider 中这么说(在“开始构建之前)。
  • @Maxim G 你确定 close() 会被自动调用吗?我不记得那样了,我找不到安迪对此的引用。
  • 所以我阅读了关于不需要关闭数据库的帖子。但是,对于“数据库”和“数据库”,人们是指SQLiteOpenHelper 还是SQLiteDatabase 并不完全清楚?我猜是前者,因为后者既可以打开读也可以写,那你怎么把它做成单例而不关闭呢?
  • 已编辑答案,仍需要一些测试。
猜你喜欢
  • 1970-01-01
  • 2013-08-22
  • 2012-01-31
  • 1970-01-01
  • 2013-08-18
  • 2020-03-07
  • 1970-01-01
  • 2020-08-24
  • 2020-04-05
相关资源
最近更新 更多