不推荐使用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);
}
答案 0 :(得分:1)
实际上只有一个SimpleCursorAdapter构造函数被描述,而不是整个类。你仍然可以使用它,但你必须使用"标准"构造函数需要"标志的值#34;参数。
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:通常由轮换导致的活动破坏/恢复(但可能由收到的电话无法控制的事件引起)。
CursorLoaders笨拙且难以实现,但确实很好地解决了这两个问题..
AsyncTasks将处理后台执行并将结果传递给ui线程并且如果你不关心问题2就可以正常工作,但是在android中有一个令人讨厌的小问题,只能导致一个问题AsyncTask一次运行(如果你想并行完成大量工作,那就太好了。)
还有其他框架可以用来做这种工作,比如rxJava和otto,但是他们需要付出相当大的努力才能最初适应(尽管可以说是值得的)。
如果您需要担心应用程序的轮换和/或中断,我建议CursorLoaders最初可能是最简单的,但仅适用于更简单的应用程序。如果您的应用程序变得复杂,请花些时间查看rxJava或Otto。
希望这会有所帮助。 附:简单的asynctask为基础的例子(避免经过测试,因为我没有你所有的资源/资源,但你明白了。)
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);
}
主要&#34;技巧&#34;我最初是用null游标创建simplecursoradapter;这允许我在屏幕上获取没有数据的列表。然后我启动一个AsyncTask,将cursoradapter传递给它并让它将光标加载到后台线程上。然后我打电话给&#34; changeCursor&#34;在适配器上,它应该使用加载的数据更新列表视图。您还可以使用onPreExecute来显示忙碌的&#34;微调器&#34;并隐藏繁忙的&#34;旋转器&#34;在onPostExecute ..只是为了让用户知道你正在做某事......哦,以防万一你错过了; onPreExecute和onPostExecute在UI线程上运行,因此可以更新UI,doInBackground在后台线程上运行..