ここが凄いよ AndroidStudioとGradle

2015/10/15 19256hit

Androidの開発環境はここ2年でものすごく変わり始めていますが、
もっともインパクトが大きい変化はEclipseからAndroid Studioへの移行でしょう。
Eclipseの開発環境は今後サポートされなくなることが告知されているので早めにAndroid Studioへ移行する必要があります。

Android StudioといえばGradleへの変化がもっとも大きなハイライトです。
Gradleがすごいよ!という話はよく聞きますが実際にどういう時に凄いかという話はあまりされていない気がします。
ということで、実際に使ってみて特に便利と感じたところを紹介します。

Gradleの凄いところ

ライブラリーの取り込みが凄い


Gradleを使って一番最初に感じるメリットがライブラリーの取り込みです。
Eclipseでライブラリーの取り込みってめんどくさいですよね
ライブラリーをダウンロードしてJarを取り込まないといけなかったりプロジェクトを読み込んでisLibraryを設定したり・・・
ライブラリーのバージョンが上がるたびに同じことの繰り返しだし、複数マシンで開発しているとマシンごとにライブラリーのバージョンが違ったりすることも

では、Gradleだとどうするかというと
build.gradleの

dependencies {

}

で囲まれた中に使用したいライブラリをcompile につづいて指定するだけ

例えばGooglePlay Servicesを取り込みたければ

compile 'com.google.android.gms:play-services:7.8.0'

と一行入れるだけであとは自動でライブラリーをダウンロードしてインポートまで完了します。
もちろん別のパソコンで開発するときもbuild.gradleを共有すれば自動的にダウンロードしてくれるのでライブラリーを共有に加えたり環境構築に手間をかける必要はありません。
バージョン番号も明記しているので間違って別のバージョンが組み込まれていたり古いバージョンが残ってしまうこともありません。

ライブラリーのバージョンについて開発中はとりあえず最新を使いたいという時もあると思います。
そういうときは+を使います。
例えばとにかく最新を使いたければ

compile 'com.google.android.gms:play-services:+'

というようにします。
これでGradleBuildが実行されるたびに最新をチェックして新しいものが有れば自動的にダウンロードしてインストールしてくれます。

この+は柔軟な指定ができて、例えばバージョン7とバージョン8で互換性がないのでバージョン7の最新版を使いたいという場合は次のように指定します。

compile 'com.google.android.gms:play-services:7.+'

このように固定値と最新を合わせて指定することができます。

2.BuildTypeとFlavorが凄い

例えば開発版では開発用のサーバーに接続していて内部のデータが異なる場合など、アプリを開発していると、開発版と正式版を同時にインストールしたいということがよく有ります。
正式版をアンインストールして開発版をインストールするとデータも全て消えるので面倒です。
AndroidではApplicationIDが同じアプリを複数インストール出来ないため、Eclipseではプロジェクトをコピペしてパッケージ名を置き換えるみたいなリスキーかつ大規模な改造をするとか処理部分をライブラリーにしてそれを読むだけのアプリを作るとか、どちらにしてもかなり面倒な作業が必要です。

Gradleを使うとデバッグ版とリリース版でパッケージを変えるなんてことが簡単にできます。

例えばデバッグで書きだした時はパッケージ名に.debugをつけるようにするにはModule内にあるbuild.gradleの

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

となっているところに、デバッグの時だけ末尾に.debugを追加するよう

debug{
applicationIdSuffix ".debug"
}

を追加して次のようにします。

buildTypes {
debug{
applicationIdSuffix ".debug"
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

これで、デバッグビルドの時とリリースビルドの時でapplicationIdを変えることが出来ます。
applicationIdが変わることでAndroidは別のアプリとして認識するので同時に製品版とデバッグ版をインストールできて、保存されるデータも別々に持つことが出来ます。

デバッグとリリースで別のサーバーに接続するには、
左上のProjectを押して、表示タイプをProjectにします。(これによりファイルシステム上のパスと表示が一致します)


srcフォルダ直下にある
main/res/values/strings.xmlを開きurlを追加します。
ここには本番用のURLをセットします。
/src/main/res/values/strings.xml

<resources>
<string name="app_name">Sample application</string>
<string name="url">http://firespeed.org</string> <!-- 追加 -->
</resources>

次に、srcフォルダ直下にdebug というフォルダを作りmain配下同様に、res/values/というフォルダを作ったらその中にstrings.xmlを追加します。
strings.xmlの書き方は普通のstrings.xmlと同様ですが、debug時だけ書き換えたい内容を入れるだけです。
/src/debug/res/values/strings.xml

<resources>
<string name="url">http://firespeed.org/debug</string> <!--テスト用サーバー -->
</resources>

このようにすることで、本番用サーバーとテスト用サーバーを書き換えることが出来ます。
URLを取得するときは、普通にxmlからStringを取得する時同様、Context#getString(int resId)を呼びます。

getString(R.string.url);

デバッグでビルドするか、リリースでビルドするかに応じて自動的にgetString()で取得する内容が変わります。
debugに書かれていないものについては自動的にmainから取得するので、書き換えたい項目だけを記載すれば大丈夫です。
この方式ではstrings.xmlだけでなくres内のファイルはどれでも好きな様に書き換えることが出来ます。
例えばrelease時だけ色を変えるとか、レイアウトを変えるとか、アイコンを変更するようなことも出来ます。

Javaの処理を書き換えたい時もあると思います。
Javaではmainとdebugを自動的にマージしてくれません。
mainとdebugに同じクラスがあるとエラーとなるので、debug同様にreleaseフォルダを作って対応します。
src/debug/java/com/example/sample/Hoge.java

public class Hoge{
// debugで使う処理
}


src/release/java/com/example/sample/Hoge.java

public class Hoge{
// releaseで使う処理
}


ファイルを丸ごと切り替えるのが大げさな場合、BuildConfig.BUILD_TYPEを使って書き換えることも出来ます。
例えばデバッグ時とリリース時でstaticな定数を書き換えるには次のようにします。

public class Hoge{
public final static String SERVER_PATH;
static {
if (BuildConfig.BUILD_TYPE.equals("debug")) {
SERVER_PATH = "http://firespeed.org/debug/"; // 開発サーバーのURL
} else {
SERVER_PATH = "http://firespeed.org/"; // 本番サーバーのURL
}
}
// 中略
}


Flavorで似たような別のアプリを作る

接続先は本番環境とテスト環境を切り替えたいけれどどちらもデバッグを使いたいというようなことも有ると思います。
そのような場合はFlavorを使うと便利です。
Flavor(味付け)という名前が示すように、本質的な部分は同じながら、一部処理を変えて別アプリを作りたいという場合などに使用します。
上記の例の他に、製品版と体験版、お客さんごとのカスタマイズ、マーケットごとの仕様調整などにも便利です。

Flavorを宣言するにはBuild.gradleのAndroid内で次のように設定します。

android{
//中略
productFlavors{
flavor1{
// flavor 1 特有の内容
}
flavor2{
// flavor 2 特有の内容
}
}
}

例えばflavor1ではアプリケーションIDをorg.firespeed.foo、ターゲットSDKバージョンを22
flavor2ではアプリケーションIDをorg.firespeed.bar、ターゲットSDKバージョンを23としたい場合は次のようにします。

android{
//中略
productFlavors{
flavor1{
// flavor 1 特有の内容
applicationId "org.firespeed.foo"
targetSdkVersion 22
}
flavor2{
// flavor 2 特有の内容
applicationId "org.firespeed.bar"
targetSdkVersion 23
}
}
}

あとの処理はBuildTypeと同様にmainと同一階層にFlavorの名前でフォルダ名を作成することで特定のFlavorだけファイルを入れ替えることが出来ます。
/src/main/res/values/strings.xml

<resources>
<string name="app_name">Sample application</string>
<string name="url">http://firespeed.org</string></resources>


/src/flavor2/res/values/strings.xml

<resources>
<string name="url">http://firespeed.org/flavor2</string> <!--Flavor2だけが使うURL -->
</resources>


Java内で処理を切り替えるときは、BuildConfig.BUILD_TYPEの代わりにBuildConfig.FLAVORを使います

public class Hoge{
public final static String SERVER_PATH;
static {
if (BuildConfig.FLAVOR.equals("flavor2")) {
SERVER_PATH = "http://firespeed.org/flavor2/"; // Flavor2だけが使うURL
} else {
SERVER_PATH = "http://firespeed.org/";
}
}
// 中略
}

起動するFlavorを変更するにはBuild Variantsを選択します。

flavorを切り替えることでどのFLAVORをデバッグ/リリースバージョンとして実行するかを決めることが出来ます。

出力するapk名を変える

複数のアプリを開発していると、どれがどのAPKかわからなくなったりします。
また、日付やバージョン番号を知りたいということもあります。
そのような場合にもbuild.gradleで設定できます。

android{
}

の中に

android.applicationVariants.all { variant ->
variant.outputs.each { output ->

}
}

を指定してファイル名を設定します。
記載方法がAndroidで使うJavaとはちょっと違って見えるかもしれませんが、要するに 引数として渡されたoutputに対して処理を行っていく形になります。
output.outputFileに出力するFileクラスのインスタンスを渡すことで、どのようにファイルを出力するかを決めることが出来ます。

たとえば<FLAVOR名>_<バージョンコード>_<ビルド日時>.apkとしたければ次のように指定します。

apply plugin: 'com.android.application'
android {
// 中略
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def flavor = variant.mergedFlavor
def file = output.outputFile
def flavorName = variant.flavorName
def versionCode = flavor.versionCode
def date = new java.text.SimpleDateFormat("yyyy-MM-dd HH.mm").format(new Date())
def fileName = "${flavorName}_${versionCode}_${date}.apk"
output.outputFile = new File(file.parent, fileName)
}
}
// 中略
}



他にもReleaseのビルドに成功したらgitにコミットするとか出来ること盛りだくさんという感じです。

Android Studioのここが凄い

Android Studioは特殊な名前になっていますが、専用設計ではなく、ベースとなるのはIntelliJ IDEAというIDEです。
なので、Android StudioがすごいというかIntteliJが凄いです。
Googleにこれまでの資産をなげうってまで移行する決心をさせたほど凄いです。
凄いことを言い始めるときりがないのですが、使っていて感じた凄いところを幾つか紹介します。

サジェストが凄い

IDEを使う最大のメリットとも言えるのがサジェスト、Android Studioはこれも良く出来ています。
例えば HogeFugaFooBarクラスがあった場合、EclipseではHogeのように前方一致で打った時だけサジェストがされていました。
それがAndroid StudioではFugaとかFooとかでもサジェストしてくれるようになりました。
これのおかげで、例えばActivityを呼び出したいけれど、Activityのファイル名を忘れた というような場合にActivityとだけ打てばMainActivityやSubActivityなどActivityの一覧が表示されるようになりました。
さらにはMainActivityの場合、MAのように頭文字だけでもサジェストしてくれますし、MaiActのように頭文字+数文字の組み合わせみたいなものでもサジェストしてくれます。

コード追跡がえらい

EclipseではF3キーを押すと、それが宣言されていたり、作成されている場所へ飛ぶ機能があります。
概ね問題なく動くのですが、問題はRクラスの中身に飛ぶ時。
RクラスはAndroidがリソースファイルを参照するために作るStaticなintの集合体を持っていて、レイアウトファイルを参照したりするのに使う

findViewById(R.id.hoge);

のR.id.hogeは、XMLを元に自動生成されたRクラスの中にあるstatic inner classであるidクラスにあるstaticでfinalなint型の数字hogeを意味します。
そのため、EclipseでF3キーを使ってR.id.hogeの宣言場所を探すと、Rクラスが開いていました。
しかし、Rクラスにあるのはintの羅列ばかりで実際にそれが役立つことは殆どありません。IDEとしての動きは正しいけれど使えない状態です。

Android Studioでは同様の機能をCommand(WindowsはCtrl)+Bキーで行います。
そして、この時、R.id.hogeはhogeを指定しているレイアウトファイルのXMLに飛びます。 便利過ぎる。

他にも変数から、宣言している場所に飛ぶと変数を宣言している場所に飛びますが、そうではなく変数の型を作成しているところに飛びたいということも良く有ります。
そのような場合はCommand(WindowsはCtrl)+Shift+Bキーで飛べます。

コードを追跡していたらInterfaceにぶつかって、実装が見られないなんてこと、よくあると思うのですが、その時はCommand(WindowsはCtrl)+Alt+Bキーでそのインターフェイスを実装しているクラス一覧やメソッド一覧が表示され飛ぶことが出来ます。

継承元のクラスに飛びたいときはCommand(WindowsはCtrl)+Uです。

Projectが便利

Android Studioに移行して最初に戸惑うのがProjectの概念かと思います。
Android StudioはProjectの考え方がEclipseと根本的に異なります。
EclipseでいうProjectはAndroid StudioではModuleと呼ばれます。 これはほぼイコールで、ビルドする単位つまりアプリやプロジェクト一つ一つがそれぞれ別のModuleとなります。

一方でEclipseでいうWorkspaceに当たるのがAndroidStudioではProjectになります。これは概念としては近いのですがノットイコールです。(Workspace的に使ってもいいけれど)
Eclipseは一度Workspaceを作ると切替が面倒だったので、よく使うProjectは全てWorkspaceに入れておくという人も多かったと思います。そのため、一つのWorkspaceには複数のProjectが入っているのが当然。
ところがEclipseにはWorkspace内のファイルが増えすぎると起動に失敗するようになり、こうなると設定ファイルを殆どクリアしてほぼ初期状態にしないといけないという厄介な問題が有りました。Projectが増えてきた時にWorkspaceの取り扱いはかなり面倒でした。

AndroidStudioではそれに比べてWorkspaceに相当するProjectの粒度がかなり細かいです。
Projectの切替は容易で、それどころか複数のProjectを複数のWindowで開くこともできます。
そのため、Projectは同じウィンドウ内に収めたくなるProjectという粒度で入れておけばよく、ライブラリーとそれを使うアプリや、Wearアプリとそれのコンパニオンアプリのように極めて関連性が高いModuleだけが同じProjectに入ります。
1Project内は1ModuleというProjectも多い、と言うかほとんどその状態になると思います。

ショートカットが凄い

ショートカットというとキーボードのショートカットキーを思い浮かべるでしょうが、それだけじゃなくAndroid Studioには様々なコードを簡単に記載する仕組みが用意されています。
Live templateを使うとよく使うコードを簡単なショートカットで入力できるようになります。

例えば、List itemsという変数があった場合、
items.for
と入力すると
items.for、fori、forrがサジェストされ、forを選ぶと自動的に

for (Item item : items) {

}

が入力されます。
複数形の変数名だったらちゃんと単数形の変数に置き換えてくれます。(あるいは型に基づく名前にすることも出来ます。)

foriだと

for (int i = items.size() - 1; i >= 0; i--) {

}

で添字iでループを回せるようになり、

forrだと

for (int i = 0; i < items.size(); i++) {

}

でforiの逆順となります。


同じように
notnullとすると

if (items != null) {

}

が入力されるという具合

独自のLiveTemplateを作ることも出来ます。
よく使う書式があったらコードを選択してTools-LiveTemplateを選び、Template名を入れるだけ、
あとはAbbreviationにTemplate名を入力するとサジェストされるようになります。
Edit variablesを選ぶことで動的に切り替えたい部分の指定も可能です。

もちろんショートカットキーも充実しています。
その中でも一番のお気に入りがshift二回押し。
これによりファイル名を入力して直接ファイルを開くことが出来ます。もちろんこの時もサジェストの時と同様、柔軟な指定方法が可能。
ツリー構造を辿る必要がなくなり数倍早くファイルを開くことが出来ます。

リソースのプレビューが便利

リソースで色や画像、文字を取得するとコード上に表示されます。

色がぱっと見えることでリソースの指定を間違えた時にすぐ気づけるほか、多少コードが長い場合でも即時にどこでリソースを取得しているかが一目瞭然です。

デバッグが便利

Android Studioのデバッグは機能面が強化されています。
特に便利に思うのが変数が変わった時に、どの変数がどのように変わったのかをインラインで表示してくれる機能です。
いちいちどの変数を取得するかを選んだりする必要はありません。


また、メモリーやCPUの使用量を時系列で見ることが出来ます。
これによりメモリーリークや、一番メモリーに負担がかかる処理を発見しやすくなりました。

かっこよく目に優しい

冗談のようですが私がAndroid Studioにして一番気に入っているのがかっこよさです。
ThemeにしてDarculaを設定した時のかっこよさはまるでAdobeのツールのようで少なくとも今までのIDEには見たことがないものです。
コードの色付にしても原色を使うのではなく全体のバランスを考えた色合いになっていてEclipseやNetBeansをカスタマイズしてもこのかっこよさには到達することが出来ませんでした。

カッコいいなんてアプリ開発に何の意味もないじゃないか? と思う人もいるかもしれませんが、2つのメリットが有ります。

まず、かっこよさがモチベーションにつながりました。
いかにも高度なことをやっていると思わせる美しいデザインと、ノイズの少ない没入感が高いデザインにより丸一日コーディングした時の集中力が増したことを感じています。

もう一つのメリットは目に優しくなったこと。濃い色と淡い色の組み合わせは全体の発光量そのものが抑えられるので長時間見た時の疲れ目が断然減りました。

最後に

ここまでEclipseと比べた場合のAndroid Studioのメリットについて紹介してきました。
もちろん、これだけでなくAndroidStudioには様々なメリットが有ります。

一つ弁解しておくと、これはEclipseとAndroid Studioの比較ではなく、あくまでEclipseに対してAndroid Studioの良いところだけを紹介しています。
もちろんEclipseの方が良かったところもあります。

ただ、Androidアプリ開発に於いてはEclipseとAndroid Studioのメリットデメリットを比較してどちらが良いかを選ぶフェーズではなく、新規プロジェクトは問答無用でAndroid Stuido、既存の保守アプリに関してもなるべく早くAndroid Studioに移行しないといけない状態です。 そのため、一方的にAndroid Studio側だけを賞賛する内容になっていることはご了承ください。

ちなみに、Google側の意向は無視したうえで、AndroidStudioに移行してよかったかどうかというと、私は100%満足しています。
2年前に移行した時は面食らいましたが、去年から特に制約がない限り殆どをAndroid Studioで開発するようになり、数ヶ月で慣れてしまいました。

前:Android6.0の新機能API 次:神機の予感YAMAHAのAVアンプRX-V479レビュー

関連キーワード

[Android][Java][モバイル][IT]

コメントを投稿する

名前URI
コメント