むらかみの雑記帳

Android とか iOS とかソフトウェア開発に関するネタ帳

ActivityのライフサイクルをUMLのステートマシン図で描いてみた

Android Dev Guide にある Activity Lifecycle に、Activity のライフサイクルの図があるのだけど、なんだか妙にわかりにくい。遷移時にどのようなイベントが発生するのかは書いてあるんだけど、肝心の状態が書かれていないからだ。

そんなわけで、UMLのステートマシン図を描いてみたよ。

f:id:tmurakam:20101113142256p:image

これでだいぶ分かりやすくなった。一応解説。

まず、基本的な状態は3つある。

  1. Active/Running : Activity が可視、フォアグランドにある状態。
  2. Paused : Activity は可視だけど、フォアグランドではない状態。他の Activity が上に重なっていて、一部がみえている状態。
  3. Stopped : 不可視な状態。他の Activity が上に完全にかぶっていて見えない状態。

また、LifeTimeという用語もあって、これは以下のようになっている。

  1. Entire Lifetime : Activity が存在している期間。上記3状態をすべて含む。
  2. Visible Lifetime : Activity が可視の期間。Active/Running と Paused 状態が含まれる。
  3. Foreground Lifetime : Activity がフォアグランドの期間。上記Active/Running 状態と同じ。

あと、Killable というのがあるが、これは他のアプリがメモリを必要としたときに強制的に殺されるかどうか、を表す。Paused と Stopped 状態は Killable だ。

上記のステートマシン図には、上記の状態と、遷移時に発生するイベントをすべて記載してある。ほとんどのイベントは Entry / Exit アクションを使って書いてあるので、わかりやすくなっていると思う。

Git for Windows の UTF-8 ファイル名対応版を作った

Git for Windows (msysGit)が日本語(UTF-8)のファイル名をきちんと処理してくれないので、パッチを作って対応するようにしてみた。

かなり苦労したが、なんとか動作するようになったのでβ版を公開 http://tmurakam.org/git/

ほとんど土日潰した、、、

Android 版EX予約で予約がうまく行かない件

Android版EX予約で予約がうまく行かない件について。さんざん調査をして試行錯誤を繰り返したのですが、正直改善の見込み薄です。AndroidWebKit 内でエラーが発生しており、エラーから復旧できる見込みがない。

こちらにも解析されている方がいらっしゃいますが、あまり解決には至っていない様子。

一応、これまでの経緯をメモしておきます。

何が問題となっているのか

Android版EX予約で予約をすすめると、予約途中で「次へ」ボタンを押したときにエラー画面に遷移し、戻れなくなります。

私が試した限りでは、時刻指定画面で「次へ」ボタンを押したときにこの現象になることが多いようです。

原因追求

問題がおきたときの Android 側のログには以下のように表示されていました。

07-06 23:09:49.676: WARN/System.err(319): java.io.IOException: SSL shutdown failed: I/O error during system call, Broken pipe
07-06 23:09:49.716: WARN/System.err(319):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativeclose(Native Method)
07-06 23:09:49.766: WARN/System.err(319):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.close(OpenSSLSocketImpl.java:958)
07-06 23:09:49.766: WARN/System.err(319):     at android.net.http.AndroidHttpClientConnection.close(AndroidHttpClientConnection.java:245)
07-06 23:09:49.776: WARN/System.err(319):     at android.net.http.HttpsConnection.closeConnection(HttpsConnection.java:387)
07-06 23:09:49.806: WARN/System.err(319):     at android.net.http.Connection.httpFailure(Connection.java:450)
07-06 23:09:49.806: WARN/System.err(319):     at android.net.http.Connection.processRequests(Connection.java:247)
07-06 23:09:49.816: WARN/System.err(319):     at android.net.http.ConnectionThread.run(ConnectionThread.java:113)
07-06 23:10:08.497: DEBUG/ExYoyaku(319): WebViewClient: error, url='https://shinkansen1.jr-central.co.jp/RSV_P/pC2/ClientService;jsessionid=oV0oYs4GA0SB7lE32gK0nxM';, desc=The Web page contains an error.

SSL の例外が起きて、スタックトレースが表示されています。これは HTTP 通信スレッド内で起こった例外です。

SSL 例外は別に問題ではなく、真の問題は android.net.http.Connection.httpFailure() が呼ばれていること。つまり、HTTPエラーが起こっているわけです。

Androidコア側のソースを repo で取り出して内容を追ってみましたが、HTTPのやりとりをしているときに例外が発生するとここに来るようです。ソースを見る限りでは1回はリトライをして、2回失敗したらコネクションをクローズ(HttpsConnection.closeConnection)に行くようになっていました。

どのような HTTP 例外が起こっているのかは不明ですが、SSL で Broken Pipe が起こっているところから見て、TCP コネクション自体が切れているように見えます。一度、Wireshark でログを見てみようかと思ってますが。

ちなみに、このエラー、最新の Android 2.2 (Froyo) でも発生します。

対処について

エラーが起こったら、復帰するのは難しいです。前のページに戻るような実装を入れようかと思ったのですが、EX予約のサイトは「戻る」ボタンを殺しています(戻るをやろうとすると、ログインしなおし)。当然、リロードもダメ。

HTTP リクエストをもう一度やり直すのが正しいのですが、それは WebKit 内部の話なので難しいです。

つーか、リトライが1回だけってのは少ないような気がする。この回数を増やせればいいのですが、残念ながらこの回数は Java の private かつ final 宣言されてるので変更できません。変更するための API もありません。

あと、ページの完全ロードが終わるまで操作させない、という処理はいれてはみたのですが、あまり改善しませんでした。

そんなこんなで、改善の目処はしばらく立ちそうにありません。。。

Mac mini に Ubuntu 10.04 を入れてみる

Mac mini の bootcamp に Ubuntu 10.04 を入れようとして死ぬほどハマったので備忘録。

基本的には、rEFIt 入れて、Bootcamp で Ubuntu を入れればよい、、、のだが、どういうわけか grub のインストールで必ず失敗する。

とりあえず普通に (hd0) に grub を入れてやる。で、rEFIt からブートすると、grub の画面になる。ここからは手探りで、

root (hd0,2)
linux /vmlinuz ro root=/dev/sda3
initrd /initrd
boot

と手で打ってやると何とか起動した。

んで、起動してから update-grub2 してやればいいわけだが、これが見事にコア吐いて死ぬ(なぜだ、、、)一応 /boot/grub/grub.cnf.new というファイルが出来ているので、これを grub.cnf にリネームしてやればいいようだが。

iOS4 では UIDatePicker の timeZone を設定しておいたほうがよい

CashFlow を US で使っている方からメールがあり、日付選択画面(UIDatePicker)の表示が日本時間になってしまうとのこと(それ以外は現地時間で出ている)。

いろいろ探ったところ、UIDatePicker の setTimeZone でタイムゾーンを設定しておく必要があるらしい。とりあえず、

[datePicker setTimeZone:[NSTimeZone systemTimeZone]];

という行を入れたところ、不具合は解消された。

で、この不具合は iOS4 でのみ発生するようだ(iPod touch や iPad では問題なし)。また、日本国内で使っている分には問題はおこらないので気づきにくい。

しかし GMT になるならともかく、なぜ日本時間になるのだ、、、どこかにそんなプロパティあったっけ、、、?