什么是实现AsyncTask
最有效的解决方案。
我有一个工作应用程序,其中我的主要 Activity 使用 listView
来显示来自数据库的结果。所有处理都在 UI 线程上进行。
但我当前的代码使用了 SQLiteDatabase
和 Cursor
对象的多种方法。最初填充 listview
和使用 CAB 删除行时。
到目前为止我所做的尝试都失败了,因为我正在访问仍在 UI 线程上的对象。我不确定我应该采取什么方法
下面是我的代码:
/** * A placeholder fragment containing a simple view. */
public static class PlaceholderFragment extends Fragment {
/** The fragment argument representing the section number for this fragment. */
private static final String ARG_SECTION_NUMBER = "section_number";
// TO and FROM arrays are used to map database columns to the corresponding elements on an XML layout file. The layout file is used by the adapter to populate the listView in the main fragment.
static final String[] FROM = { */Colums to query /*}; //end
static final int[] TO = { */destination colums /* }; // end
/** Returns a new instance of this fragment for the given section number. */
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
ListView layoutListView;
DatabaseHelper DbHelper;
SQLiteDatabase db;
Cursor cursor;
SimpleCursorAdapter adapter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Find your views
layoutListView = (ListView) getView().findViewById(R.id.listView);
// Create a new helper to control db access and get a readable copy.
DbHelper = new DatabaseHelper(getActivity());
db = DbHelper.getReadableDatabase();
}
private void updateList(){
//requery and update cursor
querydb();
//tells the adapter the cursor/data has changed
adapter.notifyDataSetChanged();
}
private void querydb() {
//specify the columns to be used in the db query
String[] queryColumnList = { */ list of colums to query /* };
// Perform a db query and store a table of results in the cursor object
cursor = db.query(
DatabaseHelper.dBContract.TABLE_NAME, //table to be queried
queryColumnList, //The columns to return
null, //The column for the where clause
null, //The values for the where clause
null, //row grouping
null, //filter row groups
null //sort order
);
//find the layout that will be used for each item in the listview
int listItemLayoutID = R.layout.row;
//create a new adapter to deal with the implementation of building a listview
adapter = new SimpleCursorAdapter(getActivity(), listItemLayoutID, cursor, FROM, TO,2); //Arguments = context, layout for each row, From variable details data source, To variable details the id values of elements in the row layout file.
//show the adapter which listview it needs to populate
layoutListView.setAdapter(adapter);
}
}
}
到目前为止我尝试了什么:
private class getListData extends AsyncTask<Void, Void, Void> {
@Override // Do the long-running work in here
protected Void doInBackground(Void... Parms) {
final String[] FROM = { */ source list /*}; //end
final int[] TO = { */ destination list /* }; // end
//specify the columns to be used in the db query
String[] queryColumnList = {
dBHelper.dBContract.clutches._ID,
dBHelper.dBContract.clutches.C_NAME,
dBHelper.dBContract.clutches.C_EGG_COUNT,
dBHelper.dBContract.clutches.C_HATCH_START,
dBHelper.dBContract.clutches.C_HATCH_END,
};
// Perform a db query and store a table of results in the cursor object
cursor = db.query(
TABLE_NAME, //table to be queried
queryColumnList, //The columns to return
null, //The column for the where clause
null, //The values for the where clause
null, //row grouping
null, //filter row groups
null //sort order
);
}
// This is called each time you call publishProgress()
protected void onProgressUpdate() {
//setProgressPercent(progress[0]);
}
@Override // This is called when doInBackground() is finished
protected void onPostExecute(Void result) {
int listItemLayoutID = R.layout.row;
adapter = new SimpleCursorAdapter(getActivity(), listItemLayoutID, cursor, FROM, TO,2);
return null;
layoutListView.setAdapter(adapter);
}
}
编辑:LogCat
05-21 08:04:44.203 1639-1653/co.uk.tickingClock.app E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1 Process: co.uk.tickingClock.app, PID: 1639 java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841) Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() at android.os.Handler.(Handler.java:200) at android.os.Handler.(Handler.java:114) at android.widget.CursorAdapter$ChangeObserver.(CursorAdapter.java:453) at android.widget.CursorAdapter.init(CursorAdapter.java:174) at android.widget.CursorAdapter.(CursorAdapter.java:149) at android.widget.ResourceCursorAdapter.(ResourceCursorAdapter.java:91) at android.widget.SimpleCursorAdapter.(SimpleCursorAdapter.java:104) at co.uk.tickingClock.app.view_clutches$PlaceholderFragment$getListOfClutches.doInBackground(view_clutches.java:282) at co.uk.tickingClock.app.view_clutches$PlaceholderFragment$getListOfClutches.doInBackground(view_clutches.java:256) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841)
最佳答案
您正在 doInBackground()
中初始化您的 SimpleCursorAdapter
。
在 onPostExecute()
中执行此操作。
关于android - 使用 AsyncTask 从数据库填充 ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23781009/