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/