【问题标题】:Why do I need a Looper in my AsyncTask?为什么我的 AsyncTask 中需要 Looper?
【发布时间】:2012-10-31 17:29:12
【问题描述】:

我想使用 AsyncTask 通过服务器更新我的 db4o。在 doInBackground 方法中,我连接到服务器,更新 db4o,并安排一个挂起的意图。不修改 UI 或显示任何 toast。

最初,我遇到以下错误:

Can't create handler inside thread that has not called Looper.prepare() 

添加 Looper.prepare() 后,工作正常,但仅适用于五次更新 (AsyncTask)。我读过这个话题:AsyncTask threads never die (Android),我现在没有失败。当我抛出第六次更新时,应用程序崩溃了:

FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
Caused by: java.lang.RuntimeException: Only one Looper may be created per thread
at android.os.Looper.prepare(Looper.java:74)
(...)

我在文档中读到我需要 Looper.loop(),但是这样,应用程序崩溃了..

例子:

protected Integer doInBackground(Void... params) {
    Looper.prepare();

        update = new Update();
        update.checknewObjects();
        update.deleteOldObjects();
        update.updateObjects();
        Looper.loop();
}

为什么需要 Looper? 为什么应用程序在五次更新后崩溃? 我可以在哪里安排 Looper.loop()?

提前致谢!

【问题讨论】:

  • “引起:java.lang.RuntimeException:每个线程只能创建一个 Looper”检查您是否在同一线程上使用 Looper 的次数不超过一次。如果您在线程内使用处理程序(主应用程序线程有一个 Looper),通常需要一个 Looper。 mindtherobot.com/blog/159/…

标签: java android android-asynctask handler looper


【解决方案1】:

如果你想使用AsyncTask那么使用它,你不应该将它与Lopper混合使用...

protected Integer doInBackground(Void... params) {}

已经在后台线程上工作,没有理由调用 Lopper,为什么?

如果您的应用程序需要进行某种长时间的计算,那么AsyncTask 是非常好的工具,因为它提供了在UI Thread 上工作的方法,并允许更新UI 并取得一些工作进展,因为每个用户都会使用您的应用程序应该知道该应用程序“正在做某事”(当它需要超过 2-5 秒时)。

而且它是通用的并且提供了一些好处。

如果您不需要更新UI,只需使用例如Handler

【讨论】:

  • 谢谢骗子.. 但是.. 如果我不使用 looper 我有以下错误: Can't create handler inside thread that has not called Looper.prepare()
  • 您的错误意味着您正在尝试从后台线程更新您的UI。这通常是不允许的。
  • Looper 也可以在 AsyncTask 中有效使用,如果您使用 AsyncTask#executeOnExecutor() 而不是 #execute(),它会将您的线程放在另一个线程池中,该线程池使用不同的 Handler AKA Looper .所以你必须调用 Looper.prepare()
【解决方案2】:

如果您想安排任务,您应该使用 Timer 和 TimerTask,据我了解,我认为它们应该更适合您的需求。 http://developer.android.com/reference/java/util/Timer.html

【讨论】:

    【解决方案3】:

    在异步任务中,你不能在后台函数中使用循环。它给出错误

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-09
      • 2012-05-21
      • 2017-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 2011-07-30
      相关资源
      最近更新 更多