2013年9月28日

Android 4.3でSurfaceViewを使うアプリがランダムにクラッシュする件

Google Playで公開しているあるアプリを更新しようと思ってテストしていると、なぜか数回に一度の割合でクラッシュする事に気付いた。

エラーの内容はこんな感じ。
java.lang.IllegalArgumentException
: at android.view.Surface.nativeUnlockCanvasAndPost(Native Method)
: at android.view.Surface.unlockCanvasAndPost(Surface.java:255)


そういえば最近Google Playの管理画面で報告されるエラーが増えてきていた。自分のテスト端末(初代Nexus7)で出ているエラーと同じものだ。


エラーが起きている端末は全てNexus7。おそらく Android 4.3 を搭載している端末で問題が発生している様な気がする。


エラーが起きるのは、SurfaceViewを使ったActivityから一旦別のActivityを起動して、また元のActivityに戻ってきた瞬間だ。毎回というわけではなく大体5回に1回ぐらいの頻度なのでやっかいだ。

Backキーでホーム画面に戻ってからまたアプリを起動した時やタスク一覧から戻ってきた時は全く問題は起きない。


調べてみると下のスレッドが見つかった。

Issue 58385 - android - android 4.3 - IllegalArgumentException at SurfaceHolder.unlockCanvasAndPost(canvas) - Android Open Source Project - Issue Tracker - Google Project Hosting 

やっぱりAndroid 4.3 のSurfaceView にはバグがあるようだ。

しかも現状では回避策は無さそう。。。

SurfaceView を使っているアプリ全てが影響を受けるとすると、結構大きな問題になるのではないだろうか。

SurfaceViewを使うのを止めて View の Canvas に描画する様に書き直して対策した、という書き込みはあった。しかも皮肉な事にハードウェアアクセラレーションのおかげでかえってFPSが改善されたとの事。

とりあえず View.isHardwareAccelerated() の戻り値を見て、trueならView+Canvasを使って、false (かつOSが4.3より前) なら SurfaceView を使う様にすればなんとかなるかも知れない。

でも、同じ事をするのに2種類の方法で実装しないと行けないとなると、これは面倒だなー。

4.3を搭載した端末が一般的になる前になんとか早く解決してくれないかな〜。




2013/09/29  追記:

そういえば、4.0以降なら TextureView があった。これを使おう!

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES. ICE_CREAM_SANDWICH){
    //TextureViewを生成
} else {
    //SurfaceViewを生成
}

テストしてみた所上手く行っているみたい。
これで今回は一応解決!