@numa08 猫耳帽子の女の子

明日目が覚めたら俺達の業界が夢のような世界になっているとイイナ。

#PHDJapan に参加して、Androidの地雷を踏みまくった

mixiで開催されたPhoto Hack Day Japanに参加をしてきました。

Photo Hack Dayとは、写真に関するアプリを実装するハッカソンです。shutterstockを始めとする主催、協賛企業が公開しているAPIを無料で利用することができるため、これらのAPIを利用して価値のあるアプリケーションの開発を行うことができます。

さて、僕達のチームは id:henteko07 が実装を行った、ランダムウォークGifアニメを作るアプリの拡張を行いました。

スマホアプリとシェア機能を追加する感じです。そして、僕はAndroid版アプリの実装を担当しました。

そこに闇は広がっていた

今にして思えば、その闇の深さはあるていどの予想はできたのです。

今回、Android版の実装を行う中で幾つもの地雷、罠にハマりました。正直、僕はAndroidアプリを仕事でも趣味でも実装していて、最近は初心者が書いたコードをレビューするポジションになったりと、自分自身Androidに対してものすごい得意だと思っていました。

しかし、実際には想定していなかった、知らなかった様々なトラップがあったわけです。これは、慢心です。

今後の自分のために、踏み抜いた地雷をリストアップしていきます。

Android4.3では、MediaStore.ACTION_VIDEO_CAPTUREで呼び出したアプリが、撮影した動画のUriを返さない。

これは、どうやらAndroid4.3のバグのようです。

ActionにMediaStore.ACTION_VIDEO_CAPTUREを指定して暗黙的インテントを発行し、ビデオの録画を行うと、呼び出し元のonActivityResultの引数として撮影をした動画のUriが渡されることになっているのですが、Android4.3ではnullが得られます。

Stack Over flowの解答で、解決策が記述されていますが未確認です。とりあえず、今回はAndroid4.3では動作をしないまま進めました。

MediaMetadataRetriver.getFrameAtTimeはややこしい

動画から指定した時間のフレームの画像を取得するメソッドですが、第一引数に時間を、第2引数に取得の際のオプションを指定しますが、適切なオプションを指定しないと狙ったタイミングの画像が取得できないようです。

動画の頭からシークを行う場合は、OPTION_CLOSEST_SYNCで問題無いっぽいですが、シークがランダムに前後する今回のようなケースでは適切なオプションを都度求める必要があるようです。

あと、このメソッドの動作はものすごい遅いです。

AndroidGifの編集には非対応

知ってたんですがね。ちゃんとした対応策を講じること無く当日に挑んだのがアレでした。「ちょっと探せばなんかちょうどいいライブラリあるだろwww」くらいの甘い考えでいましたが、AndroidJava向けのライブラリは見つけることができませんでした。結局、LibGDAndroid向けにビルドして、NDKを利用しようとしましたが、時間が無くて断念。

Gifの生成には現在非対応です。

BitmapをIntentに沢山詰め込むと、Activityが起動しない

Intentにはそもそも沢山のデータを入れるべきではないのですが、実装が面倒だったのでBitmapのリスト要素(30個くらい)をIntentに詰め込んでActivityの起動を試しました。結果として、特にエラーやログメッセージを出すこと無く(?)Activityが起動しない現象が発生。

テストの記述を怠った

バグった際の原因特定にも、ユニットテストコードの記述は役立ちますが、テストを書くこと無く進めていたために、バグの特定に時間がかかることがありました。途中から書くようにはしましたが。

DrawableAnimationでアニメーションしない

DrawableAnimation.startで、Bitmapのアニメーションをスタートしてくれると思っていたのでしたが、実際にはスタートをするタイミングが非常に重要だそうです。詳細はドキュメントに、startを呼ぶタイミングに気をつけるように書いてあります。

慢心してた

「慢心...ですって?ううん、そうかなあ...気をつけますね。」

AndroidはUIやアプリケーション、その他コンポーネントのライフサイクルや、Javaとの動作の違い、OSの差分など意識するべき項目は多いはずなのに、結構すっぽりと抜けていました。

じゃあどうする?

ちなみにHack Dayでは

デプロイゲート使いまくってたら、Proのアカウントもらえることになったよ!!やったね!!