2013-10-25 70 views
1

我在android上編寫了一個應用程序,其中通過主活動(UI線程)創建線程,新線程保存活動實例,然後在運行時調用其中的方法。android多線程中的正確設計

我得到了一個錯誤,在這個崗位找到了「內螺紋已不叫Looper.prepare()無法創建處理程序」: Can't create handler inside thread that has not called Looper.prepare()

和許多我不能叫更多的問題另一個線程的方法直接,我應該使用runOnUIThread或doInBackGround等...

我的問題是爲什麼? 該設計有什麼問題?

在此先感謝:)

+1

許多Android框架的類(尤其是UI工具箱中的類)不是線程安全的,因此在非UI線程上訪問它們可能會導致不可預知的代碼行爲。我的猜測是,您正在調用最終(可能通過其後續調用)接觸UI元素或嘗試創建「Handler」的活動方法。你能更詳細地解釋你想做什麼嗎?也許發佈一些代碼? – acj

回答

3

你似乎有點糊塗 - 問題沒有多大意義,所以這是相當難回答的問題。

星星點點:

  1. 在創建UI線程的線程「節約活動實例」是錯誤的本身:活動的生命週期是複雜的,你不應該通過實例參考。因爲對象不屬於任何線程,所以你不能「調用另一個線程的方法」(除非你的意思是java.lang.Thread對象本身,並且從上下文看來你不這樣做)。 Java中的所有對象都生活在堆上,可以被任何線程訪問。

  2. 但是由於每個線程都是一個對象,因此可以擁有一個包含線程實例索引的對象的Map。這基本上是ThreadLocal的內容。

  3. Android引入了「Loopers」的概念 - 您可以在任何線程中構建一個並調用它;如果你這樣做,你可以說線程「有一個活套」有一個線索卡住了一個循環,做任何處理程序傳遞給它的工作,並且 - 在完成每個任務之後 - 等待另一個人來。這是主線始終在做的事情。如果您構建一個處理程序實例,則可以從任何線程調用該處理程序,但連接到調用構造函數的線程的循環程序。

  4. 由於處理程序通過將工作傳遞給loopers來工作,因此它們只能在具有loopers的線程中構建。

我不知道你想達到什麼,但底線是:

  • 你持有到活動的參考想法是錯誤的 - 只是讓他走了(並用裝載機API或服務)
  • 您嘗試在不具有高枝剪(可能添加彎一些自定義的線程建立一個處理程序實例是不是你想要的,而不是你想建立的處理程序在你的主線程)
  • 你想象的對象作爲線程所有者 - 試圖擺脫這個想法,它不一致你的想法。