で、早速エラーレポートで報告されている事案の調査をしました。
ちなみに、落ちたクラス(VgeSurfaceView)のソースは↓のような感じ。
/* *------------------------------------------------------------------------ * メインループ (スレッド) *------------------------------------------------------------------------ */ @Override public void run() { SurfaceHolder holder=getHolder(); Canvas canvas; while (isAttached) { // 仮想VRAMへの描画処理 PSGTEST.setVram(vram); // 仮想VRAMを実VRAMへ転送 canvas=holder.lockCanvas(); canvas.drawBitmap(vram,vramRect,screenRect,screenPaint); holder.unlockCanvasAndPost(canvas); } } |
赤い網掛け部分がNullPointerExceptionが発生した部分。
なので、青い網掛け(lockCanvas)がnullを返したことが原因。
Android SDKのマニュアルを読んでいたら、妙な記述を発見。(以下、抜粋)
If you call this repeatedly when the Surface is not ready (before Callback.surfaceCreated or after Callback.surfaceDestroyed ), your calls will be throttled to a slow rate in order to avoid consuming CPU.
|
上記を逆説すれば、「リトライは必要」ということ。
(ついでに、リトライ時にsleepをしなくてもハングにはならないらしい)
なので、以下のように修正すればOKかな。
Invader BlockとVGE Chiptune Musicの両方に下記の対策を入れて、本日中にリリース予定です。
public void run() { SurfaceHolder holder=getHolder(); Canvas canvas; while (isAttached) { // 仮想VRAMへの描画処理 IBLOCK.setVram(vram); // 仮想VRAMを実VRAMへ転送 canvas=holder.lockCanvas(); while(null==canvas && isAttached) canvas=holder.lockCanvas(); if(null==canvas) break; canvas.drawBitmap(vram,vramRect,screenRect,screenPaint); holder.unlockCanvasAndPost(canvas); } } |
・リトライ要の場合、リトライ(Destroy時は中断して抜ける)
・リトライ中にDestroyになった場合はスレッド停止
久々にAndroidアプリ開発っぽい内容の記事でした。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。