如何在ListFragment中正确处理数据库?

时间:2016-04-28 13:30:32

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

我正在构建一个非常简单的应用,其中包含SQLiteDatabase,我希望使用自定义ListFragmentSimpleCursorAdapter中显示该内容。

我的代码工作正常,但我不确定我是否正确地做事。我已经搜索了很多(权威的)示例,但是只发现使用ArrayAdapter的过于简化的示例,或使用ContentProvider的过于复杂的示例。

ListFragment

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

}

1 个答案:

答案 0 :(得分:0)

对于简单的东西,它会起作用。但...

您是否在一个地方使用数据库?

你的数据库有多大?

你多久一次点击onResume / onPause?

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

特别是首次触摸(创建)数据库可能非常耗时,而且您可能会获得ANR

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

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