【问题标题】:Populate ListView from database with AsyncTask使用 AsyncTask 从数据库中填充 ListView
【发布时间】:2014-05-21 10:48:06
【问题描述】:

实施AsyncTask 的最有效解决方案是什么。

我有一个工作应用程序,我的主要活动使用listView 来显示来自数据库的结果。所有的处理都在 UI 线程上进行。

但我当前的代码使用SQLiteDatabaseCursor 对象多种方法。最初填充 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 进程:co.uk.tickingClock.app,PID:1639 java.lang.RuntimeException:执行 doInBackground() 时发生错误 在 android.os.AsyncTask$3.done(AsyncTask.java:300) 在 java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) 在 java.util.concurrent.FutureTask.setException(FutureTask.java:222) 在 java.util.concurrent.FutureTask.run(FutureTask.java:242) 在 android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 在 java.lang.Thread.run(Thread.java:841) 原因:java.lang.RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序 在 android.os.Handler.(Handler.java:200) 在 android.os.Handler.(Handler.java:114) 在 android.widget.CursorAdapter$ChangeObserver.(CursorAdapter.java:453) 在 android.widget.CursorAdapter.init(CursorAdapter.java:174) 在 android.widget.CursorAdapter.(CursorAdapter.java:149) 在 android.widget.ResourceCursorAdapter.(ResourceCursorAdapter.java:91) 在 android.widget.SimpleCursorAdapter.(SimpleCursorAdapter.java:104) 在 co.uk.tickingClock.app.view_clutches$PlaceholderFragment$getListOfClutches.doInBackground(view_clutches.java:282) 在 co.uk.tickingClock.app.view_clutches$PlaceholderFragment$getListOfClutches.doInBackground(view_clutches.java:256) 在 android.os.AsyncTask$2.call(AsyncTask.java:288) 在 java.util.concurrent.FutureTask.run(FutureTask.java:237) 在 android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 在 java.lang.Thread.run(Thread.java:841)

【问题讨论】:

  • 你用谷歌搜索过这个问题吗?请分享您拥有的东西,以便我们带您从那里开始。
  • 听说过 cursorloader ??
  • 你确定运行 AsyncTask 仍然卡住 UI?
  • 我已经添加了 LogCat 输出,然后使用了 Async 类

标签: android multithreading android-listview android-asynctask


【解决方案1】:

您正在doInBackground() 中初始化您的SimpleCursorAdapter。 在onPostExecute() 中执行此操作。

【讨论】:

  • 我的 Cursor 和 SQLiteDatabase 对象怎么样。它们在片段类中声明。我还能在doInBackground 代码中使用它们吗?
  • 是的,您可以,但最好确保创建 AsyncTaskFragmentActivity 不为空。
  • @DavidFinder 如果这回答了这个问题,请标记这个答案。
  • @DavidFinder 如果这解决了问题,请标记这个答案,如果没有,那么您必须发布LogCat 以获得任何帮助。
  • @DavidFinder 是的,但如果有错误,您需要分享LogCat。它可能看起来与上一个错误相似,即使它们不相关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
相关资源
最近更新 更多