我一直在UI线程上进行数据库事务,并且由于数据库很小,所以没有任何明显的UI冻结,但是我担心,因为数据库事务不应该在UI线程上进行。
我在SO上发现AsyncTask是解决此问题的最佳解决方案,但我没有看到实际的示例。而且,我从未使用过Asynctask类。
这是我从片段的onCreateView
调用的方法:
private void getBookDb () {
Log.d(TAG, "getBookDb called");
mDatabase = mBookHelper.getWritableDatabase();
Cursor cursor = mDatabase.rawQuery("SELECT * FROM " + BookEntry.NAME, null);
if (cursor != null && cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
BookItem bookItem = new BookItem();
String id = cursor.getString(cursor.getColumnIndex(BookEntry.ID));
String url = cursor.getString(cursor.getColumnIndex(BookEntry.URL));
bookItem.setProductId(id);
bookItem.setUrl(url);
}
bottomRoot.setVisibility(View.VISIBLE);
} else {
Log.d(TAG, "Database is empty");
emptyRoot.setVisibility(View.VISIBLE);
}
if (cursor != null) {
cursor.close();
}
mDatabase.close();
mBookAdapter.notifyItemRangeChanged(0, mBookAdapter.getItemCount());
}
请您告诉我如何在AsyncTask中执行此操作?
最佳答案
1)AsyncTask并不困难,对Google来说并不困难,并且有很多教程。
2)了解AsyncTask后,将对getBookDb()
的调用放入AsyncTask的doInBackground()
方法中。
3)尝试重构代码,以便在doInBackground()
结束并调用onPostExecute()
之前不必更新任何UI元素,然后在onPostExecute()
方法中进行所有UI更新,该方法将在UI线程。另外,您可以在onPreExecute()
方法中更新UI,因此请尝试在onPreExecute()
和onPostExecute()
中完成所有UI内容。
4)如果需要,您可以使用以下代码在AsyncTask的doInBackground()
方法中实际更新UI元素:
runOnUiThread(new Runnable() {
@Override
public void run() {
// Runs in the UI thread
}
});
5)另外,我相信在SQLite数据库中放置/读取信息的更好,更安全和“适当”的方法是使用
ContentValues
而不是rawQuery()
,如下所示:https://developer.android.com/training/basics/data-storage/databases.html#WriteDbRow