« 細かい書き込み連発で CPU Wait% が異常上昇 | メイン | [メモ]ツイキャスと震災と義援金について »
2011年02月08日
iPhone アプリを Android に移植したときのメモ
1月の12日に Android 端末買って、3週間後に ツイキャス・ビュワーをリリースする、という挑戦的な目標を立てていたのだけど、無事作業も完了したのでその時のメモ。
結論から書くと Android よくできてる。開発もやりやすくて楽しい。いやー、こりゃいい。
なにそれお前こないだまで iPhone 厨じゃなっかったのかコラ、と言われそうですが、開発者にとってみれば Android の方が優れてるところが多いと思います。はい、あとメモ。もう順不同でざーーーーーっと。
■初めに思ったこと
とくかく Java 嫌だ。いやいや嫌嫌面倒くさい。なんとかこれ回避できんかな、とおもって Titanium に手をだして、おぉ、こりゃいいや、となるも Android 版は完成度あと一歩のところだったので断念。
次に Adobe AIR に手をだすという苦し紛れの行動にでるも、これもあえなく断念。ま、ライブ配信系、インタープリタ二重にかませて動くほど甘くないよね、と。
■開発環境
基本 Eclipse を使うのだけど、こいつがちょいと重い。
みんながそれでも Eclipse 使いやすいというのが全く理解できなかったのだけど、使っていくうちに許せるようになってきた。
ただ、やっぱりマルチウインドウには対応して欲しいわけで・・・しかもたまにおかしな挙動で落ちるし固まるし、Clean up 実行しないとビルドできなかったりで・・・。
でも、インターフェースの設計も全部できるのはやっぱり便利だから、仕方なくこれ使うことになる、と。
■シミュレーター
iPhone アプリの開発は、なんといってもシミュレーターが秀逸で、あの高速のシミュレーターのおかげで開発効率がかなり上がる。
それにくらべて Android シミュレーターの遅いこと重いこと。
正直、デバッグは実機で、が基本かと。シミュレーターはあくまでも画面バリエーションや API Level (OSのバージョン) の検証用なんじゃないですかね。
ま、それでもあるだけ便利なんだけど。
■多言語化
iPhone は多言語化がちょっと面倒で、インターフェースの要素の文字列はプログラム的に変更してあげないといけない。
文字列リソース → getLocalizedString 使いまくりのながれ。
これに対して Android はインターフェースに直接多言語化した文字列リソースを埋め込めるので、プログラム的には楽。
ただ、Android も結局 インターフェースに対するアクションを処理するために部品パーツのインスタンスをプログラム的にもたないといけないことも多いから、手間はそれほど変わらなかったりするのだけど。
で、文字列リソースは XML ファイルなので、ここは手間省くとこでしょ!ってことで iPhoneの多言語リソースを Android の XML に変換するプログラムは書いた。
これで多言語化 40% くらい簡単になった。
■インテントとアクティビティ
Android の基本はインテントとアクティビティなんだよ、とよく言われてるけど、これちゃんと理解したのは実際にコード書いてから。
つまり、アクティビティってアプリ内アプリみたいなもんで、画面遷移を完全にコントールしている iPhone と違って、アクティビティ単位で画面を内部からも外部からも呼び出せる Android はものすごく柔軟。
いやー、こりゃ便利、と気付くまで3日くらいかかったけど。
iPhone アプリで画面遷移や、その状態インスタンスを結構根深くもってると Android への移植ではハマると思う。まぁ、MVC設計でそんなタコなことになってることはないとは思うけど、でもビューから他のビューのインスタンスを直接持ってるところがあるなら、それは Android では通用しないのでアウトってことになる。
■戻るボタン、メニューボタン最高
アクティビティが独立しているおかげで、戻るボタンがものすごく重要な意味を持つ。
ていうか超絶便利。これ、アプリまたがって戻れるから、すべてのアプリのすべての画面がそれぞれ Web ページであるかのように扱える。
いやー、よくできてる。
でもってメニュー。 Android での最大の弱点は画面サイズが端末によってバラバラなこと。それに加えて、画面遷移は自分のアプリだけじゃなくて他のアプリが間にはいってくることもあるから、変なツールバーとかいれると UI の整合性がなくなって操作的にも「???」になってしまう。
なので、Andorid ではヘタなツールバーにメニューっぽいアイコン載せるのはやめにして、すべてメニューボタンで制御する、というのがスマートなやり方なんじゃないかな。
ということで、このアクティビティとメニューの設計が超重要になってくる。
■で、移植どうすんの?
フルスクラッチでコーディングかよ、まさかね、ということで、いろいろ見ていった結果、こりゃ移植簡単じゃないか、という結論に。
MVC で設計してるから当たり前なんだけど、Mはそのまま移植OK、Cはちょっと Android の特性にあわせる必要があるけどそんなに面倒じゃない(なにしろ Android の C は基本的にはインテントなんだから)。V は癖さえつかめば全然問題なし。
ということで何やったかというと、 Objective-C のコードを放りこむと Java のコードに変換するプログラム書いて、そこにガンガンコードを放りこんで自動変換してから手で修正、ということをやった。
さる仕事でちょっと辛かったけど、やってみると意外に共通点が多くて、関数一つまるごと自動変換で完了!なんてのもざらだった。
例えば
- (BOOL) isSameUser: (NSString*) username{ return [self.mUserName isEqualToString: username]; }
ってコードを突っ込むと
public Boolean isSameUser(String username){ return mUserName.equals(username); }
に変換してれるって感じのモノ。オレオレ命名規約でガンガン変換かけるので、一般公開するようなもんじゃないけど、これで効率 50% くらいアップしたと思う(体感w)
■プログラミングして思ったこと
もう箇条書き。
- 文字列連結できるのって便利!楽
オペレーター定義素晴らしい。なんで Objective-C にはオペレーター定義がないのか・・・
- 設定メニューの作成が超絶らくちん
iPhoneで凝った設定メニューつくってたら死亡。シンプルにしておけば移植は簡単です。
ま、iPhoneでもシステムの設定メニューは簡単につくれるんだけど。
- アクティビティ独立でインスタンスはいつ消えるかわからないので、結構独立した設計が必要になる。これはまぁ、いいことかと。
- スレッドの扱いが楽
簡単にスレッドつくって Handlerでメインスレッドに戻せる。
ただし、スレッドのゴミ残すとやっかいなので注意
- コールバック楽じゃないか
いや、これは Java の設計なんだけど、クラス内クラスとか、インスタンスのメンバ関数オーバーライドとか便利すぎなわけですよ。
コードの段は深くなるけど、iPhone で必死に delegate で渡してた苦労は一体・・・
(iPhoneでも iOS4 から ^{block} 書けるようになったけど、iPad 版 iOS4 が出るついこないだまではそれも使うわけにはいかず・・・)
- クラス名.this 楽すぎ
final 変数宣言しなくていいだけなんだけど、Java いいかもと思った。
- レイアウトの設計はくせがある
いろんな画面があるので、これだけは難しい。
もう割りきって、画面サイズなんて一切とらわれないで自由な気持ちで設計するのがミソ。
・・・とはいえ、結局サイズ計算しちゃうんだけどね・・・どうしても理解できない挙動することがるので・・・
まぁ、画面については、iPhone はサイズ固定なんで超絶自由度高いですな。
コレばっかりは設計思想の違いとしか言えない。でも Android の画面も慣れだと思います。
- デザイン
Androidの画面は XML でスタイルを使い回しできるので Web に CSS はめるみたいな感じでデザインできるから便利。
この XML 組めるデザイナーさんいたらいいと思うんだけどな・・・
- Manifest
Androidでは、アクティビティつくったら Manifest で定義とかいろいろしないといけないことがある。
最初はすげー面倒なんだよこれ、って思ったけど、設計深めていくと素晴らしく便利であることに気付いた。
- 戻るボタンがあるからキーボード隠さなくていい
まぁこれもずぼらなんだけど、戻るボタンでユーザーがキーボードひっこめることができるから、プログラムで制御しなくていいから楽だと思った。
ていうか iPhone ユーザーがキーボードひっこめられないってなんかオカシイ気がするw
- Toast 便利
メッセージの表示方法なんだけど、Activity が表示されてなくてもメッセージ表示できて、こりゃ使い方次第で便利だわ、と。
- jar だけでフレームワーク/ライブラリ配布できる
iPhone では XCode のフレームワーク作成\配布が封印されていてもんもんとしてたんですが、Java だと jar で配布できるから他人のライブラリとか猛烈に使いやすいよね、と。
- Android NDK も便利
結局つかいました、NDK。 C で書かれたソースがあったので、こいつを NDK にいれたら2時間ほどで Android で動くようになりました。すばらしい
- Java 意外にはやいじゃないか
で、コーディングしながら、こんなん Java で本当にパフォーマンスでるのかよ、って思ったけど、出た。マジで出た。びっくりした。
■あと最後に
もう長くなったので、猛烈に端折るけど、いざ公開ってところで震えた。
なんせ、審査なし!$25払ってアプリ登録して Android Market で検索したらもう出てきやがる!なんだこれ!
いままでApple にさんざん悩まされてきたあの苦労、もういいのねいらないのねしなくていいのね。と。
いやー、こりゃ開発者天国だなとおもった。不具合でてもすぐに修正できるし(かといってクオリティは重要だけど)、なにより作ったけど公開できないという最悪のリスクを考える必要がない、と。
ということで、もう長すぎるので終わりますが、Android への移植は意外に簡単だし、Android の方が優れている点がたくさんあったし、なにより開発者にとても優しいのが嬉しい。
もうちょいつくりますかね、Android アプリ。
で、よかったら今回つくった ツイキャス・ビュワー、ダウンロードしていってください。
そこらのタコな実装でスレッド漏れしててアプリ閉じても裏でガンガンループまわってパケットどっさり消費する、なんてことないですから。
(いや、そんなアプリめちゃ多いと思う。自由度高すぎる弊害かもだけど。)
#あー長かった・・もっと書きたいことあるんだけどこれ以上は本出版レベルだw
投稿者 aka : 2011年02月08日 23:11 / 2011年02月 / メモ
トラックバック
このエントリーのトラックバックURL:
http://133.242.136.64/mt-tb-sf.cgi/852
コメント
Nexus S、未ログインの状態で動画を見ると、ロック画面に遷移してしまいます。
投稿者 hoge : 日時 2011年02月09日 11:40
うひゃ、mjdsk。
Android 2.3 ですかね。手元のエミュレーターでは再現しない・・ロックしてそれ解除したら見られる感じですかね。
投稿者 yoski : 日時 2011年02月09日 12:53
なんでEclair以上専用にしたんですかね?
問題がないならCupcakeやDonutに対応していただきたいのですが
投稿者 はdsn : 日時 2011年05月11日 00:27
Objective-C のコードを放りこむと Java のコードに変換するプログラムというのは、どんなメソッドを書けばいいのでしょうか。教えてください!
投稿者 P子 : 日時 2011年08月28日 22:20