Callable blocking UI

1.4k views Asked by At

I've been downloading and parsing a webpage with Jsoup, to show the content in a list. This process takes a while so I implemented Callable interface to do the task in another thread and get the result back. The problem is that it still blocks UI during the process.

public class GetListaNotizie implements Callable<ArrayList<Notizia>> {

 static ArrayList<Notizia> getNotizieBySezione() {
    [...] Long process 
    return notizie;
 }

 @Override
 public ArrayList<Notizia> call() throws Exception {
    return getNotizieBySezione();
 }
}

And then:

final ExecutorService service;
final Future<ArrayList<Notizia>> task;
service = Executors.newFixedThreadPool(1);
task = service.submit(new GetListaNotizie());
try {
    ArrayList<Notizia> notizie = task.get();
    lvListaNotizie.setAdapter(new RiempiLista(activity, notizie));
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}

What am I missing?

2

There are 2 answers

1
Brian Roach On BEST ANSWER

Because ... you're submitting your Callable to the pool, then explicitly blocking the thread waiting for it to finish.

ArrayList<Notizia> notizie = task.get();

I missed the Android tag on your Q. You're re-inventing the wheel here. Android provides AsyncTask for exactly this use case. See the AsyncTask example under Processes and Threads for an example of how it works.

(original answer follows)


You need your Callable to update/notify the UI when it's finished. One possible approach would be to pass a reference to the list you mention to your Callable.

Edit to add from comments:

Right now, you submit your Callable to the pool. Then you sit there waiting for it to finish (blocking the UI thread). Then you do this:

lvListaNotizie.setAdapter(new RiempiLista(activity, notizie));

Pass lvListaNotizie to your GetListaNotizie via a constructor and have that happen at the end of call() instead of returning the list to the Future. I don't know what lvListaNotizie is; if it's not thread-safe you will want to synchronize on it.

1
Filliny On

AsyncTask is deprecated since API level 30.

You can use coroutines documentation link for async code or you can use work manager for async long-running operations documentation link

it is too late to answer but may be useful for new developers.