2

おそらく簡単な質問があります。私はAndroidサービスを持っています。ここで、ロックを要求し、別のスレッドで実際の(拡張)サービスコードを実行する汎用サービスクラスを作成しました。以下の例:

abstract public class ParentService extends Service {


public static void getLocks(Context context) {
       //code to get locks
}

public abstract void doServiceJob();

@Override
public void onCreate() {
    super.onCreate();       
    //Run the service code in separate thread
    Thread serviceThread = new Thread() {
        public void run() {
            //Looper.prepare();
            doServiceJob();
            //Looper.loop();
        }
    };
    serviceThread.start();
}

@Override
public void onDestroy() {
       //release locks
}
}

上記の例では、Looper.prepare()とLooper.loop()が呼び出されたスレッドで呼び出されなくても、すべてが正常に機能します。

ただし、GPSまたはネットワークを介して位置情報を取得しようとすると、次に問題が発生し、「Looper.prepare()を呼び出さなかったスレッド内にハンドラーを作成できません」というコードが実行されません。

UIスレッドと通信するためにルーパーとハンドラーを作成する必要があることを理解しています。UIに影響するイベントの場合。ただし、場所の取得はUIに影響しますか?これは、ロケーションプロバイダーが電話のトップバーにもGPSアイコンを描画しようとし、UIスレッドで実行されていないためです。それはできませんか?

ここでの問題は何ですか。looper.prepare()とLooper.loop()を呼び出すことで、この問題を修正できます。しかし、私は次のことを理解する必要がありますか?

  • UIスレッドと同じメインスレッドでサービスが実行されることは知っています。つまり、サービスにはUIを変更する機能がありますが、ユーザーエクスペリエンスが良くないため、変更を加えていません。そのため、通知を通じてすべてを伝達するのでしょうか。(通知もUIスレッドで実行する必要がありますか?)
  • ロケーションプロバイダーをUIスレッドで実行する必要があるのはなぜですか?
  • ここではハンドラーを宣言していません。looper.prepare();を呼び出しているだけです。では、メッセージキューはバックグラウンドでどのように機能し、Androidコードでは以下で何が起こるのでしょうか。

これらの質問へのポインタと回答は本当に役に立ちます。よろしくお願いします。

乾杯

4

1 に答える 1

1

Looper.Loop を呼び出す必要がある理由は、バックグラウンド操作がフォアグラウンド スレッドでコードを実行するためのルートを提供するためです。バックグラウンド スレッドからのメッセージは、Handler オブジェクトを使用して UI スレッドにポストされます。これらは、UI スレッドが Looper.Loop を呼び出して実際のメッセージを処理することを要求します。ここでメッセージ処理が行われます: Looper.Loop 呼び出し内です。

于 2011-05-02T14:08:59.273 に答える