2010年6月25日金曜日

Xperiaのandroid.os.HandlerのsendMessageDelayedが不正確な問題

「魔王なんて!」をリリースしてから2週間と少し経過して、やっとバグ修正も一段落してきました。Xperiaについてかなり重要な事が分かったので情報シェアさせていただきます。

私はXperiaユーザーではないので正確なアップデート日付は分かりませんが、2010年6月中旬ぐらいのアップデートをきっかけにTimer処理がおかしくなりました。具体的にいうとandroid.os.Handlerクラスで処理しているキーリピートの間隔が急にバラバラになった事です。そのため、java.util.Timerやjava.lang.Threadに処理を置き換えましたが全くダメでした。具体的には下記のような実装をしているゲームアプリはいまごろ全てダメになっているような気がします。また、GC(ガベージコレクション)が重たくなりキーリピートがスムーズに動きません。


public class TickHandler extends Handler {
long before = 0;
long delay = 200;
public TickHandler(){
this.sleep(1000);
}

@Override
public void handleMessage(Message msg) {
long current = SystemClock.uptimeMillis();
long x = current - before;
if(x > delay){
before = current;
if(ControllerView.repeatNative)
pushRepeat(true);
}
this.sleep(10);
}

public void sleep(long delayMills) {
removeMessages(0);
sendMessageDelayed(obtainMessage(0),delayMills);
}
}



どうやって回避したかというと、下記二つの修正を行いやっと回避が出来ました。

* 「リアルタイムのインスタンス生成を(new)をとにかく減らす」
* 「GLSurfaceView.RendererのonDrawFrameのイベントでタイマー処理を統一」

2つ目の修正なのですが、どうやらOpenGLのタイマー処理だけ何故か正確だったのでこれに統一しました。どうしてもXperiaでタイマー処理がガタガタになったらこの修正を試す事をお勧めします。

0 件のコメント:

コメントを投稿