2012年2月25日土曜日

[android]バックキー押下で処理をハンドリング=Activity#finishのタイミングではない

時々、アクティビティの終了と同時に、処理を実装したいケースがあります。
外的なイベントであれば、バックキー押下がそれに当たります。
こういった場合、Activity#onKeyDownなんかで、キーコードをフックして何か処理を実施するものだと思っていましたが、コレがNGってことがわかりました。
何がNGっかというと、Activity#onKeyDownやActivity#onKeyUpでは、アクティビティの終了にならないケースがあるからです。
具体的には、以下のような流れになります。
 1.バックキー押下したままにする
 2.Aアクティビティで、画面遷移するボタンを押下
 3.Bアクティビティが表示される
 4.バックキー放す
 5.Bアクティビティはfinishしないけど、keyUpは発生する
バックキーと同期して処理を行いたい場合は、Activity#onBackPressedをオーバライドするとよさそうです。
Activity#onBackPressedは2.0以降を境に、処理タイミングが異なりますので、やや注意が必要です。
2.0以前:onKeyDownで処理
2.0以降:onKeyUpで処理。ただしonKeyDown→onKeyUpじゃないと呼び出されない

あ、ちなみに、Activity#onKeyDownでfinishと同時に、DB更新。みたいな事をやると、これ相当ヤバイ。Activity#onKeyDownは、キーを長押しすると、連続で発生するイベントだからです。

Activity#onBackPressedで、アクティビティ終了と判定した場合、Activity#isFinishingがtrueになる。コレを使うとフラグメントも含め処理がうまくいきそう!

2012年2月1日水曜日

[Android]Activity#onStartは意外に呼ばれない?

ボタンの2度押し対策として、以下のような対策を先日実施しました。


  • Activity#startActivityをオーバライド。フラグがoffならstartActivityする

  • Activity#onStartで、フラグをクリア

大体のケースでうまく行ったのですが、時々フラグがoffにならず、はてなと思っていろいろなバリエーションを調べてみると、次のアクティビティに遷移してすぐにバックキー押下みたいな操作を行うと発生することがわかりました。そこまでたどり着くのにだいぶ時間を費やしたんですが、なんでフラグがoffにならないかわかりませんでした。

で、onStartにトレースを入れてみると、呼ばれていないことがあるのがわかりました。
えぇそれが、遷移してすぐにバックキーのときです。
そのため、onResumeにフラグoffを移したら思い通りに動作するようになりました。

そういえば、上に透明なアクティビティがあるときも同じような現象があった気がします。
これは、Activityが不可視状態に遷移することなく、元に戻ったタイミングである。と考えるとまぁ納得がいきますね。