A Day In The Life

とあるプログラマの備忘録

開発者目線でAndroidとiPhoneを比較してみる

iPhoneAndroid 両方のアプリ開発を経験したので両者を比較してみます。

OS

iPhone
Android

開発言語/開発環境

iPhone
Android

動作環境

iPhone

フレームワーク

iPhone
Android

MVCパターンからみた違い

iPhone
  • Model
    • Core Data(iPhone OS 3.0以降)
  • View
    • UIViewのサブクラス
    • Interface Builerを使ってデザイン
    • デザインの情報は xib ファイルに保存される(中はXML)
  • Controller
    • UIViewController
      • UINavigationController
      • UIImagePickerController
      • UITabbarController
      • UITableViewController
Android
  • Model
    • ContentProvider
  • View
    • android.view,android.widget パッケージにある部品群
    • レイアウト XML にデザイン定義を書く
    • デザインの情報は xml ファイルに保存される
  • Controller
    • Activity
      • ListActivity
      • MapActivity
      • ExpandableListActivity
      • TabActivity

Controllerの実装方法

ラベルに文字列をセットする場合の比較

iPhone
@interface HogeViewController : UIViewController {
  UILabel *label;
}
@property (nonatomic, retain) IBOutlet UILabel *label;
@end

@implementation
@synthesize label;
- (void)viewDidLoad {
  [super viewDidLoad];
  label.text = @"Hello world!";
}
- (void)dealloc {
  // メモリ領域の開放
  [label release];
  [super dealloc];
}
@end
Android
public class HogeActivity extends Activity {
  private TextView label;
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    label = (TextView)findViewById(R.id.label);
    label.setText("Hello world!");
  }
}

イベントの仕組み

iPhone
  • Target Action
  • Responder Chain
Android
  • イベントリスナー

Controller クラスのライフサイクル

iPhone
  1. loadView
  2. viewDidLoad
  3. viewWillAppear
  4. viewDidAppear
  5. viewWillDisappear
  6. viewDidDisappear

詳しくはこちら

Android
  1. onCreate
  2. onStart
  3. onResume
  4. onPause
  5. onStop
  6. onDestroy

メモリ領域圧迫時のイベント

iPhone
  • didReceiveMemoryWarning
  • viewDidUnload
Android
  • onLowMemory
詳しくはこちらを参照してください

データ保存の仕組み(データの永続化)

Android の場合 Content Provider クラスを使用することで他のアプリとデータベースを共有することができます。iPhone は今のところデータベースがアプリごとに独立しているので他のアプリと共有することはできないようです。両者ともデータ保存に SQLite が使えます。

iPhone
Android
  • SharedPreferencesクラス
  • ContentProviderクラス
  • その他 Java の機能を使った永続化

ちょっとしたデータの保存には iPhone の場合は NSUserDefaults クラス、Android の場合は SharedPreferences クラスを使います。どちらも Key-Value 形式でデータを永続化できます。詳しくは下記の記事をご覧ください。

マルチタスク

iOSマルチタスクというよりもマルチアプリという印象です。

iPhone

iOS 4.0以降で可能

Android

可能

バックグラウンドプロセス

iPhone
  • 音楽再生
  • 位置情報の取得
  • VoIP
  • 一定時間内であればその他処理も可能
Android

サービスクラスを使っていろいろな処理をバックグラウンド実行できる。

グラフィック

Android でグラフィック系のアプリをつくる時は、UI スレッドとは別のスレッドで動く SurfaceView を使うのが一般的です。

iPhone
Android
  • 2D
    • SGL
    • android.graphicsパッケージにある部品群
  • 3D
  • ベクターグラフィック
    • 非対応(代わりに9-patchを使う)

アニメーション

iPhone
Android
  • android.view.animationパッケージにある部品群

加速度計

iPhone
  • UIAccelerometer(加速度計の管理)
  • UIAccelerometerDelegate(加速度イベント)
Android
  • 加速度計に限らずあらゆるセンサーを管理する SensorManager クラスがありそこで管理されている
  • SensorManager(センサーの管理)
  • SensorListener(センサーイベント)
詳しい比較はこちらを参照してください

リソース

iPhone

  • Resourcesフォルダ以下に保存
  • NSBundleクラスからmainBundleオブジェクトを取得する

    // 画像のパスを取得する
    NSString *imagePath = [NSBundle mainBundle] pathForResource:@"Hoge" ofType:@"png"];
    UIImage *image = [UIImage imageAtPath:imagePath];
    

Android

  • Resourcesフォルダ以下に保存
  • Rクラスの定義を使って取得する

    // Activityクラスでの取得方法
    Drawable drawableb = getResources().getDrawable(R.drawable.hoge)
    

国際化

iPhone

  • 言語.lproj フォルダを作成しそこに Localizable.strings ファイルを格納する
  • Localizable.stringsファイルにローカライズしたメッセージを格納する

    Resouces
    |--English.lproj
    |  `--Localizable.strings
    `--Japanese.lproj
       `--Localizable.strings


  • /English.lproj/Localizable.strings

    "Hoge";
    "Fuga";


  • /Japanese.lproj/Localizable.strings

    "Hoge" = "ほげ";
    "Fuga" = "ふが";


  • ローカライズされた文字列はNSLocalizedString関数で取得する

    // 英語環境だと"Hoge"日本語環境だと"ほげ"が取得できる(第2引数はコメント)
    NSString *str = NSLocalizedString(@"Hoge", @"");
    


  • Localizable.strings以外にもプロパティリストや nib ファイル、SQLite データベース、画像などもローカライズできる

Android

  • 各言語ごとに/res/valuesフォルダを作成しstrings.xmlファイルを格納する

    res
    |--values-en
    |  `--strings.xml
    `--values-ja
       `--strings.xml


  • 今のところ文字列以外はローカライズできない模様

ロケーション

iPhone
  • Core Location
    • CLLocationManager
    • CLLocationManagerDelegate
  • CLLocationManagerを直接インスタンス化できる
Android

電子コンパス

iPhone

CLLocationManager で磁北も真北も取得できる。

Android

磁北を取得するのであれば SensorManager を使って取得できる。真北をとるには SensorManager に加え LocationManager と GeoMagneticFieldを使う必要がある。

詳しい比較はこちらを参照してください

アプリケーション間連携

iPhone はシングルタスクだからアプリ間連携ができないとかよく聞きますがiPhoneでもアプリ間連携ができます。ただ Android に比べると動きがぎこちない上に実装が複雑です。iOS 4.0 以上でだいぶ改善しています。

iPhone

  1. UIApplication クラスのインスタンスを sharedApplication メソッドを使って取得する
  2. UIApplication インスタンスの openURL メソッドを使って呼び出す。

    NSURL *url = [URL URLWithString:@"http://www.google.com"];
    [[UIApplication sharedApplication] openURL:url];
    

連携できるアプリのURL一覧は以下を参照してください。

なおここで紹介した方法は連携というよりも他のアプリを単に呼び出すだけですが、連携ぽっく呼び出し元に戻す方法もあります。

Android

  1. Intent のインスタンスを生成する。
  2. Activity クラスの startActivity メソッドを呼び出す。引数には Intent のインスタンスを渡す。

    public class HogeActivity extends Activity {
      :
      public void onClick(View v) {
        // ブラウザを起動
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
        startActivity(intent);
      }
    }
    

連携できるアプリについては以下を参照してください。

通知機能

iPhone Android ともに通知の機能があります。

詳しい比較はこちらを参照してください
iPhone

Android は小さな PC、iPhoneiPhone

iPhone OS はタッチスクリーンで動くことを前提にタッチスクリーン用に開発されていますがAndroid OS は何が何でもタッチスクリーンというわけではなくどちらかというと PC 系の OS(WindowsMac)に近い感じです。
両者の最大の違いはカーソルキーの存在です。iPhone 端末はタッチスクリーンに最適化するためカーソルキーがありません。強いて言うならユーザの目線がカーソルの役割を果たします。
逆に一般的な Android 端末にはキーボードのカーソルキーとマウスの特性が合体したポインティングデバイスが存在します。Android であれば割と簡単にカーソルキーととキーボードだけで動くアプリを開発することができます。
iPhone は純粋にタッチのみで動かすことを前提に設計されているのに対し、Android はタッチ+カーソルキーをつかう前提になっていることがこの違いを生み出したのだと考えています。
Android の方が従来の PC の特性を多く持っていることから「Android は小さな PC、iPhone は小さな PC とは違う別の新しいもの」という印象があります。
頑張れば iPhone でも Android でも同じようなアプリを開発できますが、お互い得意とするところが違うためそれぞれの特徴を生かしたアプリを開発をすることをおすすめします。
※上記例外としてソニエリXperia があります。XperiaAndroid端末として考えると痛い目に合うような気がします。Xperia は別物だと考えています。