• スポンサードリンク

SurfaceViewでsurfaceDestroyedが呼ばれない時がある

Android Camera SurfaceView widget

Androidのアプリで頻繁に描画を更新したい時、カメラを使う時などに、SurfaceViewを使いますよね。例えばカメラを使う時だと、surfaceCreatedかsurfaceChangedでカメラをopenしてsurfaceDestroyedでreleaseしたりしますよね。

よくあるサンプルだと、例えばこんな感じ(CameraのプレビューをSurfaceViewへ描画するときのSurfaceHolder.Callback)

ところがですよ、surfaceDestroyedを思ったタイミングで呼んでもらえない時が有るんです。
ふつ〜にアプリを立ち上げて、バックキーで終了してとかであれば、Activityのライフサイクルに合わせてsurfaceCreated→ surfaceChanged→ surfaceDestroyedと呼ばれるので何の問題もありません。

でも、例えば電源ボタンを押して画面を消すとActivityは通常通りにonPause→onStopまではイベントが発生するものの、surfaceは残ったままでsurfaceDestroyedも呼ばれません。
カメラを使っていればそのまま裏で動きっぱなし、SurfaceViewの描画更新のためにスレッドを生成してたり、Runnableで周期的にオートフォーカス等の処理を行っているとそれも動きっぱなしのお行儀の悪いアプリになってしまいます。ガ━━(;゚Д゚)━━ン!!

対応策ですが、まずはSurfaceが存在しているかどうかを保持するためのprivateなフィールドを設けてsurfaceCreatedでtrueにセット、surfaceDestroyedでクリアします。
その上で
1.ActivityやFragmentのonPause/onStopとonResume/onStartでSurfaceが存在しているかどうかに合わせて処理を停止・復帰処理を行ってあげる。

例えばこんな感じ(SurfaceViewを使ってカメラのプレビューを表示するActivityのコードを抜粋)

»

  • スポンサードリンク