1

我在android上写了一个应用程序,其中通过主活动(UI线程)创建一个线程,新线程保存活动实例,然后在运行时调用其中的一个方法。

我收到一个错误“无法在未调用 Looper.prepare() 的线程内创建处理程序”并在这篇文章中发现: 无法在未调用 Looper.prepare() 的线程内创建处理程序

在更多我不能直接调用另一个线程的方法的问题中,我应该使用 runOnUIThread 或 doInBackGround 等等......

我的问题是为什么?那个设计有什么问题?

提前致谢 :)

4

1 回答 1

3

你似乎有点困惑——这个问题没有多大意义,所以很难回答。

点点滴滴:

  1. 在 UI 线程中创建一个“保存活动实例”的线程本身就是错误的:活动的生命周期很复杂,您不应该通过实例来引用它。

  2. 您不能“调用另一个线程的方法”(除非您指的是 java.lang.Thread 对象本身,而从上下文看来您没有),因为对象不属于任何线程。Java 中的所有对象都存在于堆上,并且可以被任何线程访问。

  3. 但是由于每个线程都是一个对象,因此您可以拥有一个 Map 来保存由线程实例索引的对象。这基本上就是 ThreadLocal。

  4. Android 引入了“Loopers”的概念——你可以在任何线程中构建一个并调用它;如果你这样做了,你可以说线程“有一个弯针”具有 Looper的线程被卡在一个循环中,执行处理程序传递给它的任何工作,并且 - 在完成每个任务后 - 等待另一个任务的到来。这就是主线程一直在做的事情。如果构建处理程序实例,则可以从任何线程调用处理程序,但连接到调用构造函数的线程的循环器。

  5. 由于处理程序通过将工作传递给 looper 来工作,因此它们只能构建在具有 looper 的线程中。

我不确定你想要实现什么,但底线是:

  • 您持有对 Activity 的引用的想法是错误的 - 放手吧(并使用 Loader API 或服务)
  • 您尝试在一些没有 Lopper 的自定义线程上构建 Handler 实例(可能添加 Looper 不是您想要的,而是您想在主线程中构建 Handler)
  • 您将对象想象为由线程拥有-尝试摆脱这种想法,它会扭曲您的思维方式。
于 2013-10-25T21:01:46.217 回答