1

メインアクティビティ(UIスレッド)を介してスレッドが作成されるAndroidでアプリを作成しました。新しいスレッドはアクティビティインスタンスを保存し、実行中にメソッドを呼び出します。

「Looper.prepare() を呼び出していないスレッド内でハンドラーを作成できません」というエラーが発生し、次の投稿でわかりました: Looper.prepare() を呼び出していないスレッド内でハンドラーを作成できません

そして、別のスレッドのメソッドを直接呼び出すことができないという多くの質問では、runOnUIThread または doInBackGround などを使用する必要があります...

私の質問はなぜですか?そのデザインの何が問題になっていますか?

前もって感謝します :)

4

1 に答える 1

3

あなたは少し混乱しているようです - 質問はあまり意味をなさないので、答えるのはかなり難しいです.

小片:

  1. 「アクティビティ インスタンスを保存する」UI スレッドでスレッドを作成すること自体が間違っています。アクティビティのライフサイクルは複雑であり、インスタンスで参照するべきではありません。

  2. オブジェクトはどのスレッドにも属していないため、「別のスレッドのメソッドを呼び出す」ことはできません (java.lang.Thread オブジェクト自体を意味する場合を除き、コンテキストからはそうではないように思われます)。Java のすべてのオブジェクトはヒープ上に存在し、任意のスレッドからアクセスできます。

  3. しかし、各スレッドはオブジェクトであるため、スレッド インスタンスによってインデックス付けされたオブジェクトを保持する Map を持つことができます。これが基本的に ThreadLocal です。

  4. Android では「ルーパー」の概念が導入されています。任意のスレッドで作成して呼び出すことができます。もしそうなら、そのスレッドには「ルーパーがある」と言えます。ルーパーを持つスレッドは、ハンドラーから渡されたすべての作業を実行し、各タスクを終了した後、別のタスクが来るのを待って、ループにスタックします。これは、メインスレッドが常に行うことです。ハンドラー インスタンスを作成すると、ハンドラーは任意のスレッドから呼び出すことができますが、コンストラクターを呼び出したスレッドのルーパーに接続されます。

  5. ハンドラは作業をルーパーに渡すことで機能するため、ルーパーを持つスレッドでのみ構築できます。

何を達成したいのかわかりませんが、要点は次のとおりです。

  • Activity への参照を保持するというあなたの考えは間違っています - それを手放してください (そして Loader API または Service を使用してください)
  • Lopper を持たないカスタム スレッドで Handler インスタンスを構築しようとした場合 (おそらく、ルーパーを追加することは目的ではなく、代わりにメイン スレッドで Handler を構築する必要があります)
  • オブジェクトがスレッドによって所有されていると想像している - この考えを取り除こうとしてください。それはあなたの考え方をゆがめます。
于 2013-10-25T21:01:46.217 に答える