/var/log/messages

May 20, 2015 - 3 minute read - Comments - Git android

eclipse から AndroidStudio への移行

とりあえず、build.gradle で云々するプロジェクトだったので import から build.gradle を読み込みました。

その後、productFlavor な機能を盛り込んでみたのでそちら方面のメモを残しておきたいと思います。

eclipse で云々していた頃は

  • 開発
  • 配布
  • 配布その 2

みたいなカンジで branch しておいて

  • Manifest の中のパケジ文字列 sed で修正
  • ソース中の package とか import とか intent-filter な文字列 sed で書き換え
  • ContentProvider なソースの provider な記述を sed 書き換え
  • preferences な XML の intent な記述を sed で書き換え

みたいな下準備をした後に ./gradlew が kick off されるスクリプトを使っておりました。また、今回の移行で判明したのですが branch 間の差分に現れない差分が盛り込まれていたりして (URL 文字列など) 色々な意味で bad な手法が駆使 (?) されておりましたが、このたび productFlavor を使うことにより、非常にシンプルな形 (?) でこうした差分を管理することができるようになりました。

移行後

とりあえず上述の通りで一つの端末に三つくらいの版が同居できなければならない、ということで productFlavor という機能を使ってみました。これ便利です。

以下なカンジでアプリのパケジ名を変えることができる模様。

productFlavors {
    develop {
        applicationId = 'fuga.hoge.dev'
    }
    product {
        applicationId = 'fuga.hoge'
    }
    staging {
        applicationId = 'fuga.hoge.staging'
    }
}

パケジ名として valid ではないあたりはスルーでお願いします。そしてこの仕組みですが src 配下が以下のような構成になっていれば

+-- src --+-- main --+-- assets
                     |
                     +-- java
                     |
                     +-- jniLibs
                     |
                     +-- res
                     |
                     +-- AndroidManifest.xml

src 配下に develop や product や staging というディレクトリを掘ってあげることで

  • AndroidManifest.xml
  • res 配下のリソース

を productFlavor 毎で管理する、ということが可能なようです。例えば URL なんかが開発版、ステージング、本番で異なる場合とか便利そうですよね。以下なカンジにしてあげれば良いみたいです。

+-- src --+--  main  --+-- assets
          |            |
          |            +-- java
          |            |
          |            +-- jniLibs
          |            |
          |            +-- res
          |            |
          |            +-- AndroidManifest.xml
          |
          +-- develop -+-- res
          |            |
          |            +-- AndroidManifest.xml
          |
          +-- product -+-- res
          |            |
          |            +-- AndroidManifest.xml
          |
          +-- staging -+-- res
                       |
                       +-- AndroidManifest.xml

main に文字通り主たる記述を盛り込んでおいて他のディレクトリには差分情報を盛り込む形になります。

ContentProvider 関連

ただ、アプリ内で ContentProvider を持って云々している場合、リソースを切り替えるだけでは間に合わなくなってしまいます。authorities 属性です。手持ちのプロジェクトだと

  • ContentProvider 継承クラスの定義で static な文字列として保持
  • AndroidManifest.xml で直接記述

という形になっておりました。以前はここも branch 毎で差分がある状態で commit を作ってそれを引き継いでおりました。かなりのヤッツケ仕事っぷりです。

とは言え static な文字列とかどうすんの、という話なのですが、このあたりも Gradle がよしなに解決してくれるみたいです。productFlavors の定義を以下のようにしてあげることで

productFlavors {
    develop {
        applicationId = 'fuga.hoge.dev'
        buildConfigField "String", "PROVIDER_AUTHORITY", "\"fuga.hoge.dev.provider\""
    }
    product {
        applicationId = 'fuga.hoge'
        buildConfigField "String", "PROVIDER_AUTHORITY", "\"fuga.hoge.provider\""
    }
    staging {
        applicationId = 'fuga.hoge.staging'
        buildConfigField "String", "PROVIDER_AUTHORITY", "\"fuga.hoge.staging.provider\""
    }
}

BuildConfig というクラスの static な属性が作られるようです。これを使って ContentProvider では以下のようにしておいて

private static final String AUTHORITY = BuildConfig.PROVIDER_AUTHORITY;

AndroidManifest.xml 側では以下のような記述にしています。

<provider android:name=".FugaHogeProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false" />