ここでは、HandlerThreadが便利な実際の生活の例です。カメラプレビューフレームに登録すると、onPreviewFrame()
コールバックでそれらを受信します。 documentationは、を説明しています。このコールバックは、スレッドopen(int)がから呼び出されたイベントで呼び出されます。
通常、これはメイン(UI)スレッドでコールバックが呼び出されることを意味します。したがって、巨大なピクセル配列を処理するタスクは、メニューが開いたり、アニメーションがアニメーション化されたり、画面上に統計が表示されたりしてもスタックしないことがあります。
簡単な解決策は、(私はpost(Runnable)
を通してそれをやった、あなたはHandler.Callback
を実装する必要はありません)。このスレッドにnew HandlerThread()
とデリゲートCamera.open()
を作成することです。
カメラでの他のすべての作業は通常どおり行うことができますが、Camera.startPreview()
またはCamera.setPreviewCallback()
をHandlerThreadに委任する必要はありません。安全な側になるためには、は、Camera.open(int)
が完了するまで待ってからを待ってから、メインスレッド(または変更前にCamera.open()
を呼び出すために使用されたスレッド)を続行します。
だから、あなたはコードで始まる場合
try {
mCamera = Camera.open(1);
}
catch (RuntimeException e) {
Log.e(LOG_TAG, "failed to open front camera");
}
// some code that uses mCamera immediately
最初の抽出物には、プライベートメソッドにあるよう:
private void oldOpenCamera() {
try {
mCamera = Camera.open(1);
}
catch (RuntimeException e) {
Log.e(LOG_TAG, "failed to open front camera");
}
}
との代わりに、単にnewOpencamera()
を使用oldOpenCamera()
を呼び出します:
private void newOpenCamera() {
if (mThread == null) {
mThread = new CameraHandlerThread();
}
synchronized (mThread) {
mThread.openCamera();
}
}
private CameraHandlerThread mThread = null;
private static class CameraHandlerThread extends HandlerThread {
Handler mHandler = null;
CameraHandlerThread() {
super("CameraHandlerThread");
start();
mHandler = new Handler(getLooper());
}
synchronized void notifyCameraOpened() {
notify();
}
void openCamera() {
mHandler.post(new Runnable() {
@Override
public void run() {
oldOpenCamera();
notifyCameraOpened();
}
});
try {
wait();
}
catch (InterruptedException e) {
Log.w(LOG_TAG, "wait was interrupted");
}
}
}
注全体を通知することを() - あなたはそれを開いた後、すぐに元のコードにmCameraにアクセスしない場合待ち()スレッド間通信は必要ありません。
更新:がここに同じアプローチが加速度計に適用されます:Acclerometer Sensor in Separate Thread
私はHandlerThreadを使用したことがない、多分この記事が役立ちます - http://stackoverflow.com/questions/7462098/handlerthread-vs-executor -when-is-one-more-over-the-other –
@TalKanel:返信ありがとうございます。私はこの記事をチェックしましたが、HandlerThread上のExecutorの利点について話しています。私の質問は、HandlerThreadを使うのに最も良いユースケースと似ています。 – Androidme
その投稿もこの問題に対処しています。エグゼキュータは、スレッドのプールを管理できるという点でより柔軟性があります。複数のスレッド - Executorを使用する必要があります。シングルスレッド - HandlerThreadを使うことができます。実行者coulcが両方の状況をカバーしているので重要ではない。私が理解しているように、HandlerThreadでは、バックグラウンドスレッドでハンドラを作成することができます。これは、他の方法でも実行できるものです。 – Rarw