android - 用于在 ListView 中显示 SQLite 记录的 SimpleCursorAdaptor 替代方案

标签 android sqlite listview

SimpleCursorAdaptor 已弃用。我发现它对我来说不是理想的,因为它使用 UI 线程,我将显示几百条记录。我想使用一些使用后台线程的东西。经过一些研究,我发现了 CursorLoader。我一直在看教程,但我发现实现起来真的很棘手。如果有 CursorLoader 的更好替代品,请告诉我。请有人帮助我。我到目前为止的代码。是:

public void getListFromDb(){
    Cursor res = myDb.ViewAll();
    startManagingCursor(res);


    //Map cursor from db to viewFields
    String[] fromFieldNames = new String[]{DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4, DatabaseHelper.COL_5};
    int[] toViewIDS = new int[]{R.id.viewName, R.id.viewAddress, R.id.viewPostcode, R.id.viewType};

    //Create adaptor to map items from DB to UI
    SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter(this, R.id.item_layout, res, fromFieldNames, toViewIDS);

    // Set adaptor for listView
    ListView myList = (ListView) findViewById(R.id.listViewLocations);
    myList.setAdapter(myCursorAdaptor);

}

最佳答案

实际上只有一个 SimpleCursorAdapter 构造函数被 depricated,而不是整个类。您仍然可以使用它,但您必须使用“标准”构造函数,它需要“标志”参数的值。

public void getListFromDb(){
    Cursor res = myDb.ViewAll();
    startManagingCursor(res);


    //Map cursor from db to viewFields
    String[] fromFieldNames = new String[]{DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4, DatabaseHelper.COL_5};
    int[] toViewIDS = new int[]{R.id.viewName, R.id.viewAddress, R.id.viewPostcode, R.id.viewType};

    //Create adaptor to map items from DB to UI
    // *** ADD THE FLAGS PARAMETER ***
    SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter(this, R.id.item_layout, res, fromFieldNames, toViewIDS, FLAG_AUTO_REQUERY);

    // Set adaptor for listView
    ListView myList = (ListView) findViewById(R.id.listViewLocations);
    myList.setAdapter(myCursorAdaptor);

}

我添加了“FLAG_AUTO_REQUERY”以使更改变得明显,但我怀疑您可能希望使用值“0”(无标志),除非您的数据在显示时可以更改。

因此,在重新阅读您的问题(抱歉,我的问题;我真的应该更仔细地阅读 :-p )之后,您真正的问题是如何在后台线程上加载数据。有很多方法可以做到这一点,都有优点和缺点。

这个经典的 Android 问题有两个部分: 1:实际上是在一个后台线程加载数据,并将结果交给UI线程显示。 2:Surviving Activity 破坏/恢复通常是由轮换引起的(但也可能是由某些无法控制的事情引起的,例如接到电话)。

CursorLoaders 笨拙且难以实现,但实际上很好地解决了这两个问题..

AsyncTasks将处理后台执行并将结果传递给 ui 线程,如果你不关心问题 2,它会很好地工作,但是在 android 中有一个讨厌的小问题,它可能导致一次只运行一个 AsyncTask(如果你不是很好想并行做很多工作)。

还有其他框架可用于完成此类工作,如 rxJava 和 otto,但它们需要付出相当大的努力才能在一开始就适应(尽管可以说是值得的)。

如果您需要担心应用程序的旋转和/或中断,我建议 CursorLoaders 最初可能是最简单的,但仅适用于更简单的应用程序。如果您的应用程序将变得复杂,请花一些时间研究 rxJava 或 Otto。

希望这对您有所帮助。 附言基于简单异步任务的示例(还没有测试,因为我没有你所有的源/资源,但你明白了..)

public void getListFromDb(){

        //Map cursor from db to viewFields
        String[] fromFieldNames = new String[]{DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4, DatabaseHelper.COL_5};
        int[] toViewIDS = new int[]{R.id.viewName, R.id.viewAddress, R.id.viewPostcode, R.id.viewType};


        // Notice I am passing null as the cursor..
        SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter(this, R.id.item_layout, null, fromFieldNames, toViewIDS, 0);
        // Set adaptor for listView
        ListView myList = (ListView) findViewById(R.id.listViewLocations);
        myList.setAdapter(myCursorAdaptor);

        new AsyncTask<SimpleCursorAdapter, Void, Cursor>() {
            private SimpleCursorAdapter mSimpleCursorAdapter;
            @Override
            protected Cursor doInBackground(SimpleCursorAdapter... params) {
                // Save cursorAdapter to use in postExecute
                this.mSimpleCursorAdapter = params[0];
                // Load cursor on background thread
                return myDb.ViewAll();
            }

            @Override
            protected void onPostExecute(Cursor cursor) {
                super.onPostExecute(cursor);
                // and update the cursor (which is already in the listview)
                this.mSimpleCursorAdapter.changeCursor(cursor);
            }
        }.execute(myCursorAdaptor);

    }

它的主要“技巧”是我最初创建了带有空游标的 simplecursoradapter;这使我可以在没有数据的情况下在屏幕上获取列表。然后我启动一个 AsyncTask,将 cursoradapter 传递给它并让它在后台线程上加载游标。然后我在适配器上调用“changeCursor”,它应该用加载的数据更新 ListView 。您还可以使用 onPreExecute 显示忙碌的“微调器”并在 onPostExecute 中隐藏忙碌的“微调器”。只是为了让用户知道您正在做某事。哦,以防万一您错过了它; onPreExecute 和 onPostExecute 在 UI 线程上运行,因此可以更新 UI,doInBackground 在后台线程上运行..

关于android - 用于在 ListView 中显示 SQLite 记录的 SimpleCursorAdaptor 替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34560484/

相关文章:

android - 两个外部第三方混淆库中的重复类名

Android:获取当前设备方向

java - 如何在 android 中设置单个 listView 项目的样式?

android - 检索特定列的数据并将其存储在字符串数组中

sql - 如何删除 sqlite 中的重复行,其中包括 ID 的每一列都是重复的?

c# - 从数据表(Windows 窗体)填充 ListView 或列表框

android - 空 ListView,如何在 ListView 为空时显示消息?

java - 无法在文件中写入字节

java - 如何通过 Intent 从 Activity 向服务发送数据 - 空指针问题

python - 如何使用python在二维网格中找到最近的相邻点坐标