user1908375
user1908375

Reputation: 1089

Updating ListView Adapter from AsyncTask

what I have is an AsyncTask, that started as soon as ListView reached bottom item on a screen, and in AsyncTask it adds new items to the ListView.

Here is the code:

    @Override
    protected void onPostExecute(final List<ItemDailyRecord> records) {
        super.onPostExecute(records);
        ((ActivityHome)context).runOnUiThread(new Runnable() {
            public void run() {

                for (ItemDailyRecord p : records) {
                    adapter.add(p);
                }

                adapter.notifyDataSetChanged();
            }
        });

    }

 @Override
    protected List<ItemDailyRecord> doInBackground(Void... voids) {

        DbAdapterDailyRecord db = new DbAdapterDailyRecord(context);
        List<ItemDailyRecord> list = db.getRecordsFromTo(offset, count);

        return list;
    }

here is a method from ListView Adapter:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if(position == getCount() - 1 && hasMoreItems){
            HistoryLoaderTask t = new HistoryLoaderTask(position + 1, pageSize, getContext(),this);
            t.execute();
            footer.setText("Loading . . .");
        }

And the error message is(if I scroll the listview too fast :)

Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

any ideas how to solve this issue?

Upvotes: 0

Views: 3407

Answers (2)

rahul.taicho
rahul.taicho

Reputation: 1379

You shouldn't execute your async task from getView of your adapter. Instead you should try to do it from your activity/fragment where your list resides by using getLastVisiblePosition() of ListView

Like this --->

if(list.getLastVisiblePosition() == (dataSet.size() - 1)) {
// last item displayed
.... change the text off footer and execute async task
}

and in the async task append the extra data to dataset and then call notifyDataSetChanged() on the adapter.

Upvotes: 0

Eugene S
Eugene S

Reputation: 3122

The onPostExecute() method is executed on the UI thread, so you should be updating the UI directly in this method; no need to spawn a new Runnable object.

Upvotes: 1

Related Questions