android多线程中的正确设计

时间:2013-10-25 20:42:44

标签: java android multithreading android-asynctask

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

我收到错误“无法在未调用Looper.prepare()的线程内创建处理程序”并在此帖中找到: Can't create handler inside thread that has not called Looper.prepare()

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

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

提前感谢:)

1 个答案:

答案 0 :(得分:3)

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

比特:

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

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

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

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

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

  6. 我不确定你想要达到什么目标,但最重要的是:

    • 您持有对Activity的引用的想法是错误的 - 只需放手(并使用Loader API或服务)
    • 你试图在一些没有Lopper的自定义线程上构建一个Handler实例(可能添加looper不是你想要的,而是你想在主线程中构建Handler)
    • 你想象对象是由线程拥有的 - 试图摆脱这个想法,它会扭曲你的思维方式。