Androidアプリを開発していると、開発版とリリース版のアプリを同時に入れておきたいことがあると思います。通常Appliction ID (com.ninjinkun.njkapp
のようなやつ) が同一だとアプリが上書きされてしまうのですが、Build Variantsを使う事で別のApplication IDを割り振ることができます。
build.gradle
productFlavors { staging { setApplicationId("com.ninjinkun.njkapp.staging") } production { } }
Manifest Placeholder
この辺りは去年からできたのですが、 ContentProvider
や BroadcastReceiver
を使っている場合、Android ManifestにApplication IDが文字列で埋め込まれており、自動的に置換されずにインストール時にエラーが出てしまう問題がありました (com.ninjinkun.njkapp
に対応するアプリケーションはないという感じの文句が出た記憶) 。しかし今年の4月下旬にリリースされた Manifest Manager のPlaceholder機能を使って、Android Manifestに変数が埋め込めるようになりました。以下のように設定することで、エラー問題が解決できます。
AndroidManifest.xml
<provider android:name="com.ninjinkun.njkapp.NJKProvider" android:authorities="${applicationId}" android:exported="false" />
Placeholderの応用
また、build.gradle
で自由に変数を定義することもできます。これを使う事で、開発用アプリを別名にできます。
build.gradle
defaultConfig { manifestPlaceholders = [appName:"@string/app_name"] } productFlavors { staging { manifestPlaceholders = [appName:"@string/app_name_staging"] } production { } }
AndroidManifest.xml
<application android:name="com.ninjinkun.njkapp.Application" android:icon="@drawable/ic_launcher" android:label="${appName}" > <activity android:name="com.ninjinkun.njkapp.MainActivity" android:label="${appName}" android:launchMode="singleTop" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> ...
category.LAUNCHAER
になっているActiviyのlabelを変更しないとランチャーでのアプリ名が変わらないのに注意。AndroidManifestを自由に書き換えられるので、アプリアイコンを変えることもできると思います。
BuildConfigField
サーバーの本番/開発機を振り分けるために、以下のbuildConfigField
を設定しています。
build.gradle
productFlavors { staging { buildConfigField "boolean", "SERVER_PRODUCTION", "false" } production { buildConfigField "boolean", "SERVER_PRODUCTION", "true" } }
コードから使うときは以下のようにBuildConfig
クラスの定数として参照できます。
public String getHost() { if (BuildConfig.SERVER_PRODUCTION) { return context.getString(R.string.host_production); } else { return context.getString(R.string.host_staging); } }
まとめ
以上の設定をまとめて、仕事で使っているbuild.gradle
のBuild Variants
まわりはだいたい以下のようになっています (名前空間だけ変えました)。
build.gradle
defaultConfig { manifestPlaceholders = [appName:"@string/app_name"] } productFlavors { staging { setApplicationId("com.ninjinkun.njkapp.staging") buildConfigField "boolean", "SERVER_PRODUCTION", "false" manifestPlaceholders = [appName:"@string/app_name"] } production { buildConfigField "boolean", "SERVER_PRODUCTION", "true" } }
補足: Build Variantsについて
ビルド構成を決めるBuild Variantsについては先ほどのnobuokaさんの記事に詳細な解説があるので、ここでは簡単な説明だけしておきます。
Build VariantsはProduct Flavors
とBuild Types
の組み合わせで表現されます。
- Product Flavors
- アプリに別名を付けたり、一部を変更したりしてリリースする為の仕組み
- Flavor毎にAndroidManifestやリソースを持つことが出来る
manifestPlaceholders
が使える- アプリ名などを変更可能
- Build Types
- アプリのビルド設定を切り替えるための仕組み
- デフォルトではdebug / releaseが用意される
- releaseでビルドすると最適化や圧縮が行われる
Product Flavorsがstaging/production、Build Typesがdebug/releaseだと以下の様に組み合わせから選べるようになります。
2014/9/5 追記
manifestPlaceholders
はただの変数なので、設定を追加したい場合はハッシュの後ろに追記する必要があります。
manifestPlaceholders = [appName:"@string/app_name", gaCode:"@string/ga_code"]