Android SDK は Eclipse 前提でだいたい話が進むので、かたくなに Eclipse を使わないようにしているといらない苦労を負いすぎます (リソース管理とか)。ので、これを期に Eclipse と連携させて Vim を使う環境をつくりました。
AutoComplPop の設定
.vimrc に追記
let g:AutoComplPop_Behavior = { \ 'java' : [ \ { \ 'command' : "\<C-n>", \ 'pattern' : '\k\k$', \ 'excluded' : '^$', \ 'repeat' : 0, \ }, \ { \ 'command' : "\<C-x>\<C-u>", \ 'pattern' : '\k\k$', \ 'excluded' : '^$', \ 'repeat' : 0, \ }, \ { \ 'command' : "\<C-x>\<C-f>", \ 'pattern' : (has('win32') || has('win64') ? '\f[/\\]\f*$' : '\f[/]\f*$'), \ 'excluded' : '[*/\\][/\\]\f*$\|[^[:print:]]\f*$', \ 'repeat' : 1, \ } \ ] \ }
キーワードマッチしなければ eclipse に投げる (めっちゃ重い)。
保存すると自動で :Validate が走る。:lope で確認できる。+sign つきで vim がコンパイルされているならいい感じにでてくる!
:Validate が走るタイミングが保存よりも早いときがあってちょっと変
http://eclim.org/vim/java/import.html
:JavaImpl すると override できるメソッド一覧がでてくるので、適当に RET おすと テンプレートが挿入される。便利なんだけど、Vim の undo が効かなくなってしまうのであんまり使ってない (表示させてコピペ、っていう使いかたをしてる)
ハッシュを自由に作れないのが LL に比べて極めて不便なので、つどデータクラスを作るわけですが、getter setter 作るのが死ぬほどめんどい。
メモリが限られていると頻繁に OOM エラーがでますが、OOM エラーは出さないことが大前提なので、頑張って何が容量食ってるか調べないといけません。まぁ、コード的に勘が効く部分は良いのですが、ライブラリに隠蔽されていたり、普段 LL 使ってると見落したりする部分があるのでちゃんと計測したいもんです。
http://www.eclipse.org/mat/ をいれる。
エミュレータでアプリケーションを起動して、ある程度動かしてから
↑ のボタンを押す
メモリーリークしているっぽいものまで解析してくれる。すごい
Histogram -> ソート -> 右クリック -> List objects でどんなオブジェクトがみれるっぽい。List objects の outgoing incoming はよくわからない。
開発中これを使ったら、画像のURLを保持する的な部分で随分メモリを食っていることが分ったので、はてな記法のみを保持してURLとかは必要なときだけ更めて生成 (パフォーマンスは劣化しますがOOMでるよりはマシです) するようにしたらだいぶ改善しました。
あと、スレッドの一覧を見ながら動かして想定通りのスレッド数かを観察するのも大事だと思いました。HttpClient はインスタンスごとにプールスレッドを持つので注意が必要でした (若干反則な気がしますが static に確保するようにしました)
はてなアカウント管理を作るにあたり、最初は Android のパーミッションの仕組みにのっかろうと考えていましたが、調べていくうちにセキュリティリスクがあることがわかったので、別途自力でユーザにオプトインする仕組みを入れました。(はてな以外からリリースされるアプリケーションでは、アカウント管理に情報を渡す際に本当に渡すかをユーザに同意を求めるようになっています)
Android のパーミッションの仕組みは「先に定義したもん勝ち」という感じのようなので、端末デフォルトでインストールされていて、アンインストールが不可能になっているアプリケーションでのみ、安全に働くようでした。なんかやりかたがあるのかよくわかりませんが、そんな感じでしたので、今のところ一番確実な方法を選んでいます。
手元の実機 (Android 1.6) での検証では
A の signature と B, C の signature は別
→ 正常
→ 正常 (この場合 B をインストールしなおすしかないのでユーザビリティ的に問題があるため採用できない)
Bがユーザへの確認なしに、不正にパーミッションを行使していることになる。
パーミッションのテストみたいなのは死ぬほどめんどいです。コマンドラインからやってもめんどい。
adb install は PackageManager を使わないのでダメです。もちろんちゃんと sign した apk じゃないとダメです。
adb push Foo.apk /sdcard adb shell am start -a android.intent.action.VIEW -t application/vnd.android.package-archive -d file:///sdcard/Foo.apk
でインストール
adb uninstall com.example.foo
でアンインストール (パッケージ名を指定するみたいです)
ちまたの sdcard からアプリをインストールするやつは、上記 Intent を投げているだけなので、特別パーミッションがいらないはずですが、なんかやたらパーミッションを要求するのが多くて、開発者以外にテストしてもらう際に困ります。
全くパーミッションを要求しないやつには com.mmg.appin というものがあるっぽいです。
Fotolife for Androidがリリースされました。
期間的にはだいたい1ヶ月で、そんなに短かいわけではないのですが、割と大変でした。Android ケータイはもちろん持っていて、使っていたわけですが、開発は Scala で rake 使って Hello, World! を動かす程度しかやっておらず (いろいろ間違ってる)、Java 自体、Rhino、Scala で間接的に一部 API を使ったことがあるだけで、ちゃんと Java のコードを書いたのは開発が決まってからでした。
「Java の文法・API」と「Android の API・バッドノウハウ」の二重でハマるので、特に最初の2週間は、アプリケーションも形にならず (アップロードもできず、表示もろくにできなかった)、たいへんしんどかったです。ちゃんとしたマルチスレッドも、普段 Perl, JavaScript ばかりなので同期方に慣れずに苦労しました (Ruby も割とシングルスレッド脳で書いてるし)、というか、いまもしてます。
スレッドまわりに関しては「Java 言語で学ぶデザインパターン入門 マルチスレッド編」を借りて読んだり、「Java 並行処理プログラミング」を買ってもらって読んだりしてみました。どちらも解りやすく、後者は特に何を使うべきかが明確で実践に即応用できたので良かったです。java.util.concurrent スゲー! ってことで使いまくってます。ソースコードは Future だらけです。new Thread() を全然書いてないです。
基本的に、Android の開発は Google のオフィシャルのドキュメントをちゃんと熟読するのが近道だと思いました。あと、それだけだと、僕みたいなのは頭に入ってこないので、android のレポジトリを全部落としてきてデフォルトで入っているアプリのソースを読むのがいいと思いました。SDK のサンプルは最小限で、それはそれでいいのですが、もっと具体的にどうするのかがよくわからなかったりするので、やっぱちゃんと動いてるコードは偉大です。
Java は食わず嫌いでしたが、やってみると案外楽しくて、思ったより書いていてイライラしない言語だなぁと思いました。基本部分のAPI (特に Stream 系) は死ぬほど冗長で意味がわからないのですが、Android 関係の API は割と普通に使える印象でした。(そのうち書きますが Eclipse と Vim を連携させて書いてます) 匿名クラス萌えです。
id:secondlife さんディレクションのもと開発し、id:nagayama さんに各種アイコンのデザイン、id:aaron さんに英語リソースのチェックをしてもらい、id:tikeda さん、id:hakobe932 さんに直前にフィードバックを貰いました。
しばらく社内用に書いたノウハウを公開していこうと思います。Fotolife for Android のAPI (インテント) も公開するので少々お待ちください。