【问题标题】:Callable blocking UI可调用的阻塞 UI
【发布时间】:2013-12-21 18:56:17
【问题描述】:

我一直在使用 Jsoup 下载和解析网页,以在列表中显示内容。这个过程需要一段时间,所以我实现了Callable 接口在另一个线程中执行任务并返回结果。 问题是在这个过程中它仍然会阻塞 UI。

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

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

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

然后:

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();
}

我错过了什么?

【问题讨论】:

  • task.get() 呼叫被阻塞。无论如何,您不需要使用 executors 和 futures 重新发明轮子。 Android 已经有一个AsyncTask精确地 用于这些类型的任务。

标签: java android multithreading callable


【解决方案1】:

因为...您将Callable 提交到池中,然后显式阻塞等待它完成的线程。

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

我错过了你 Q 上的 Android 标签。你在这里重新发明轮子。 Android 为这个用例提供了AsyncTask。请参阅Processes and Threads 下的 AsyncTask 示例,了解其工作原理。

原答案如下


您需要您的Callable 在完成后更新/通知 UI。一种可能的方法是将您提到的列表的引用传递给您的Callable

编辑以从 cmets 添加:

现在,您将Callable 提交到池中。然后你坐在那里等待它完成(阻塞 UI 线程)。然后你这样做:

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

通过构造函数将lvListaNotizie 传递给您的GetListaNotizie,并在call() 的末尾发生这种情况,而不是将列表返回给Future。我不知道lvListaNotizie 是什么;如果它不是线程安全的,则需要在其上进行同步。

【讨论】:

  • 我不确定我是否理解你所说的。你能写一个例子吗?
【解决方案2】:

AsyncTask 自 API 级别 30 起已弃用。

您可以将协程 documentation link 用于异步代码 或者您可以使用工作管理器进行异步长时间运行的操作documentation link

现在回答为时已晚,但可能对新开发人员有用。

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
相关资源
最近更新 更多