1

私はServiceクラスを拡張し、着信メッセージを処理するために別のスレッドを使用するサービスに取り組んでいるので、onCreateメソッドに次のものがあります

thread = new HandlerThread("MYSERVICE-THREAD",
        Process.THREAD_PRIORITY_BACKGROUND);

thread.start();
serviceLooper = thread.getLooper();
serviceHandler = new ServiceHandler(mServiceLooper);

このスレッドでは、LocationManagerを作成し、場所の変更をリッスンするように設定します。ただし、スレッドのライフサイクルについては少し心配です。これが理由です:

サービスのonDestroyメソッドでロケーションマネージャーからロケーションリスナーを削除せず、telnet経由でロケーションを強制的に更新しない場合、すべてが正常に機能します。私はこれが奇妙であることに気づき、サービスのonDestroyメソッドでthread.quit()を使用してスレッドを明示的に終了しようとしました。そのため、telnetから位置情報を更新すると、そもそも予想していた警告が表示されます。ハンドラーがデッドスレッドでハンドラーを呼び出していたこと。

ロケーションマネージャからロケーションリスナーを削除すると、明らかにこれが解決されますが、これは、スレッドを明示的に閉じない場合、サービスが破棄された後もスレッドが実行され続けることを示唆しているようです。これは正しいです?developer.android.comの例では、スレッドを明示的に閉じていないため、この場合はVMがそれを処理すると思いました。

4

2 に答える 2

3

そうそう。これが事実です。同じことがアクティビティにも当てはまります。スレッドは、自分で閉じない限り、Androidが明示的に強制終了してリソースを解放するまで開いたままになります。技術的な意味では、スタックからポップされたときにアクティビティとサービスが閉じられることはありません。これは、使用していたすべてのリソースを必要なときに再利用できるようになったことをOSに通知するだけなので、メモリプールがOSの最初の場所になります。ただし、任意の種類のスレッドがまだ実行されている場合は、メモリが再利用されるまで実行され続けます(CPUリソースを消費します)。これは、1秒から永遠の間のどこかになります。

于 2012-05-26T15:10:16.237 に答える
2

これは、スレッドを明示的に閉じないと、サービスが破棄された後もスレッドが実行され続けることを示唆しているようです。これは正しいです?

絶対。スレッドをフォークする場合は、クリーンアップする必要があります。

そのため、この場合はVMが処理すると思いました。

そうですね、最終的には、OSがアプリのプロセス全体を最終的に終了する限りです。そうは言っても、スレッドをリークしたくないし、実際requestLocationUpdates()には通話(または使用しているもの)をリークしたくないのです。これLocationManagerにより、ロケーションプロバイダーの電源をオンに保つことができます(GPSなど)。

developer.android.comの例では、スレッドを明示的に閉じていません

どの例を参照していますか?

于 2012-05-26T15:12:29.063 に答える