我一直在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

07-24 09:47
查看更多