hishidaの開発blog

EBシリーズ(EBPocket,EBWin,EBMac,EBStudio),KWIC Finder,xdoc2txt,読書尚友の開発者ブログ

EclipseからAndroid Studio に乗り換えた

Androidの開発環境は当初はEclipse+ADTプラグインだったが、現在はGoogle公式の開発環境はAndroid Studioになっており、ADTの更新は2015年末で終了している。Andoroid Studioに乗り換える必要を感じていたものの、NDKの移植がうまくいかないために、延び延びになっていた。
ところがGoogle さんからの一通のメールでAndroid Studioに移行せざるを得なくなった。

Android 向け Google Mobile Ads SDK の 6.4.1 以前のバージョンは、2016 年 9 月 15 日をもってサポートを終了させていただきます。
2016 年 9 月 15 日以降も引き続き広告を配信していただくには、Google Mobile Ads SDK を 7.0.0 以降のバージョンにアップグレードしてください。
SDK をアップグレードするには、Play 開発者サービスの最新バージョン(バージョンは dependencies セクションで確認)を Gradle Build 設定ファイルに追加してください。次の例では v9.0 を追加しています。

apply plugin: 'com.android.application'
...
dependencies {
compile 'com.google.android.gms:play-services:9.0.2'
}

うーん、そうですか。EBPocket Freeも読書尚友 FreeもGoogle Mobile Ads SDK 6.4.1なので、バージョンアップしないと9/15以降広告収入が途絶えることになる。世の中の流れとしてAndroid Studio用以外の開発情報が少なくなっているので、この機会にAndroid Studioに乗り換えることにした。この作業が予想以上に大変だったので、忘備録として書いておくことにする。

1. Eclipseのプロジェクトのインポート

Android Studioには既存のEclipseのプロジェクトをインポートする機能があり、"Import project(Eclipse ADT,Gradle,etc.)"を実行するだけで簡単に取り込める。100% Javaの読書尚友はこれだけでOK。問題はNDKを使用しているEBPocketである。

2. NDKのコンパイルAndroid.mkで行う

Android Studioは1.3からNDKをサポートするようになったが、色々不完全でGradleのバージョン毎に設定方法が変わったりしている。jni/ディレクトリにC/C++言語のソースを入れておけばAndroid.mkは不要でコンパイルしてくれることになっているが、これが曲者でどうしてもNDKのコンパイルが通らない。既存のAndroid.mkでNDKをコンパイルする方法を探したところ、次のページを見つけた。
Android StudioでNDKを使ったビルドをする
ほぼこのページの説明通りで、既存のAndroid.mkでコンパイルできるようになった。Cソース内のデバックができるかどうか不明だが、とりあえずAndroid Studioへの移行に成功。

3. com.google.android.gms:play-servicesの導入

続いてGoogle Mobile Ads SDKのバージョンを6.4.1から最新版の9.2.1にしてみる。

  1. app/libs/GoogleAdMobAdsSdk-6.4.1.jar を削除する
  2. build.gradleに追加

build.gradle

    defaultConfig {
		...
        minSdkVersion 9			// 9以上
		...
	}
	dependencies {
	...
	//    compile files('libs/GoogleAdMobAdsSdk-6.4.1.jar')
		compile 'com.google.android.gms:play-services-ads:9.2.1'
	}

AndroidManifest.xml

		<meta-data android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <!--
        <activity
            android:name="com.google.ads.AdActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
            -->
       <activity
            android:name="com.google.android.gms.ads.AdActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />

main_pager.xml

【変更前】
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
【変更後】
xmlns:ads="http://schemas.android.com/apk/res-auto"

【変更前】
<com.google.ads.AdView
        android:id="@+id/adView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        ads:adSize="SMART_BANNER"
        ads:adUnitId="....."
        ads:loadAdOnCreate="true" />
【変更後】
<com.google.android.gms.ads.AdView
	android:id="@+id/adView"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:layout_alignParentBottom="true"
	ads:adSize="SMART_BANNER"
        ads:adUnitId="....."
		/>

com.google.android.gms.ads.AdViewではada:loadAdOnCreateがなくなってJava内でloadAdしないといけなくなったので、onCreate()に記述を追加。

AdView adView = (AdView) this.findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);

Android Studio を使い始めると、Eclipseより便利なところも不便なところも両方あるが、なにしろGoogleの開発速度が異様に速いので、問題点は急速に解決されることだろう。継続的なサポートのためには、なるべくAndroid Studioに移行することが望ましい。
Android Studio2.1になってエミュレータの速度が向上して実機以上の速度で動くようになった。これだけでも非常に開発が捗るというものだ。

今回のはまりどころ:play-services はモジュール単位で使うべし!

冒頭のGoogleのメールに記載された例では、

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

のようにcom.google.android.gms:play-services を丸ごと指定しているが、この方法はお勧めできない。
Androidはアプリ内で定義しているメソッド数(依存ライブラリも含む)が65k(65536)を超えると、ビルドできなくなる問題があり、play-servicesには大量のメソッドを含んでいるために、簡単に65kの制限を超えてしまう。その場合はMultidexにするか、使用するメソッド数を65k未満に収めないといけない。
MultidexはAPI14以上でないとサポートされないという別の問題があるので、できればメソッド数を65k未満に抑えたほうがいい。
実はgms:play-servicesはモジュール化されており、必要なモジュールだけ選択すれば、65k未満に抑えることができる。
今回のようにadsモジュールだけ使用したい場合は、次のように記述する。

compile 'com.google.android.gms:play-services-ads:9.2.1'

Multidex化する方法

API14以上しかサポートしないからMultidexでいいよ、という場合は、次のようにするとMultidex化できる。
(バージョンは適宜変えてください)

build.gradle:

buildToolsVersion "23.0.2"
...
defaultConfig {
		...
        minSdkVersion 14			// 14以上
        ...
        // Enabling multidex support.
        multiDexEnabled true
}
	
dependencies {
  compile 'com.android.support:multidex:1.0.0'
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>

    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
    </application>

Android Studioのheapサイズ不足でAPKが作れないと言われた場合は、gradle.propertiesに次の記述を追加

org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m