1

I have a button. On click, I am refreshing a list.

What I am experiencing:

The state_pressed color stays for a big while (meaning the UI thread blocked)
(Note: the button background is defined such as on state_pressed="true" the color changes)

Question:

How can I click the button to refresh the list, without blocking the UI?

My Code:

mButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        refreshListView(data);
    }
});

public void refreshListView(ArrayList data) {
    // I am setting setNotifyOnChange() to false
    // to prevent notifyDataSetChanged() to be triggered twice, by clear() and by addAll()
    mArrayAdapter.setNotifyOnChange(false)
    mArrayAdapter.clear();
    mArrayAdapter.addAll(data);
    // I am triggering notifyDataSetChanged() explicitely
    mArrayAdapter.notifyDataSetChanged();
    mListView.post(new Runnable() {
        @Override
        public void run() {
            // this is to reset to the top of the list, after the list has been populated
            mListView.setSelectionAfterHeaderView();
        }
    });
}

EDIT:

I think I solved it by calling the refresh code from a View.post(), but I wonder if this should always be needed:

mButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        mListView.post(new Runnable() {
            @Override
            public void run() {
                refreshListView(data);
            }
        });
    }
});
Daniele B
  • 19,801
  • 29
  • 115
  • 173
  • Looking at your code, I don't think the problem area is in the above code... Is mArrayAdapter is standard adapter or custom ? If it is custom, is it having some data processing which may be taking longer time ? I had this issue in past where my adapter was having image to be grabbed from server and to be shown... I had to put that on AsyncTask... – Atul Dravid - White Pvt. Ltd. Aug 29 '14 at 20:17
  • @AtulDravid-WhitePvt.Ltd., it's a custom adapter, but it uses already processed data. I just realized I can solve the problem by calling `refreshListView()` from within a `View.post()`. Is it a good solution? – Daniele B Aug 29 '14 at 20:21

1 Answers1

0

Your refreshList should be running on ui thread... and new Runnable should be used in conjunction with thread... If you are not creating new Thread, you will be using Runnable as kind of anonymous class... As par android this is not good practice... But, well if this solves your problem, technically there is nothing wrong in your code...

  • As far I understand, `View.post()` is also a way to postpone UI-thread operations (to the end of the current UI-thread queue), from within the UI-thread. In this case, I am postponing the refreshing of the listview to when the button click action has ended. In this way the button doesn't get stuck on the state_pressed, as the UI-thread seems to get blocked by the list refreshing operation. Although I do find it strange that the listview should block the UI thread visibly. – Daniele B Aug 29 '14 at 20:41
  • I never used View.post... Can you try not to just use it ? The view.post may be causing some kind of bottleneck on Ui thread I guess... – Atul Dravid - White Pvt. Ltd. Aug 29 '14 at 20:52
  • I think `view.post()` is just postponing UI operations. It shouldn't cause bottlenecks. For example, inside the `refreshListView()` function, I am using it to reset the list to the top, after the list has been populated. I wouldn't know how to achieve the same thing in another way. – Daniele B Aug 29 '14 at 20:56
  • Hmmm... Have you tried the option which you have suggested ? Did that gave you result ? If yes, I don't think you are doing anything wrong in that. It is just that it is little different use of Runnable... – Atul Dravid - White Pvt. Ltd. Aug 29 '14 at 21:05
  • You can also use Handler to do this... Handler can allow you to execute the processing by sending it a message... I use Handlers more often with Threads as combination... – Atul Dravid - White Pvt. Ltd. Aug 29 '14 at 21:15
  • Yes, that solution with `View.post()` works, because it's postponing the list refreshing after the conclusion of the click event. I think also `Handler`s could be a solution, but `post()` is more specific about UI. – Daniele B Aug 29 '14 at 21:27
  • Good... Actually Handler is also for UI but handler is more of message driven... I normally use Handler to have better control... – Atul Dravid - White Pvt. Ltd. Aug 29 '14 at 21:46
  • You should have to post the whole method call. I'm with Atul in that you are bottle necking the UI thread somewhere else. Post your custom adapter class. – Ifrit Aug 30 '14 at 14:36