【Flutter/Dart】google_mobile_ads導入エラー奮闘記

技術

こんにちは。ざわかける!のざわ(@zw_kakeru)です。

現在、2021年の3月です。
つい先日、Flutter2がリリースされ、同時にgoogle_mobile_adsが発表されました。
Widgetとして扱える広告が公式で実装されたみたいですね。
この記事では新登場したこのgoogle_mobile_adsを早速使ってみようとゼロからプロジェクトに導入した際に大量に出てきたワケ分からんエラーの解消メモです。
エラーが出た順番に記載していきます。

動作環境

macOS: 11.2.2 (Big Sur)
Flutter: 2.0.1
Dart: 2.12.0
Visual Studio Code: 1.53.2

エラーが出るまでにやったこと

  1. Google AdMobでアカウント作成。
  2. 広告ユニット作成。

ここまではめちゃめちゃ分かりやすいFlutter公式動画の通りに順調に進みました。

その後も動画に倣ってandroid/app/src/main/AndroidManifest.xmlにメタデータを追記しました。

// (略) //
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-XXXXXXXXXXXXXXX/XXXXXXXXXXX" />
    </application>
</manifest>

一旦ここで実行します。

Error:uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:google_mobile_ads]

最初に出てきたエラーがこれでした。

/hoge/AndroidManifest.xml Error:
uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:google_mobile_ads] /hoge/build/google_mobile_ads/intermediates/library_manifest/debug/AndroidManifest.xml as the library might be using APIs not available in 16
Suggestion: use a compatible library with a minSdk of at most 16,
or increase this project's minSdk version to at least 19,
or use tools:overrideLibrary="io.flutter.plugins.googlemobileads" to force usage (may lead to runtime failures)

FAILURE: Build failed with an exception.

SDKのバージョン対応エラーですね。さっそく新ライブラリ導入の洗礼を受けました。
google_mobile_adsSDK(AndroidStudio)のバージョンが19以上にのみ対応とのことです。
エラーメッセージの言う通りに、android/app/build.gradleminSdkVersionを16から19に上げました。

defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "hoge"
        minSdkVersion 19
        targetSdkVersion 29
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

保存して実行します。

Failed to apply plugin [id ‘com.android.internal.version-check’] Minimum supported Gradle version is 6.5. Current version is 5.6.4.

次に出たエラーがこれでした。

FAILURE: Build failed with an exception.
 Where:
 Build file '/usr/local/bin/flutter/.pub-cache/hosted/pub.dartlang.org/google_mobile_ads-0.11.0+3/android/build.gradle' line: 22
 What went wrong:
 A problem occurred evaluating root project 'google_mobile_ads'. 
   Failed to apply plugin [id 'com.android.internal.version-check']
   Minimum supported Gradle version is 6.5. Current version is 5.6.4. If using the gradle wrapper, try editing the distributionUrl in /usr/local/bin/flutter/.pub-cache/hosted/pub.dartlang.org/google_mobile_ads-0.11.0+3/android/gradle/wrapper/gradle-wrapper.properties to gradle-6.5-all.zip 

今度はGradleのバージョン対応エラーです。
google_mobile_ads対応Gradleバージョンは6.5以上のみで現在は5.6.4になってるよ、とのことです。
こちらも言われるがままにandroid/app/gradle/wrapper/gradle-wrapper.propertiesdistributionUrlを5.6.4から6.5に変更しました。

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

ついでに、エラーについて調べている際にgoogle_mobile_ads公式ドキュメントを読んでいると、“Android Gradle Plugin 4.1 or higher”の記載を発見。こちらもバージョンアップ対応必須とのこと。
なので、android/build.gradleからAndroid Gradle Pluginのバージョンを3.5から4.1に変更しました。

buildscript {
// (略) //

    dependencies {
        classpath 'com.android.tools.build:gradle:4.1.0' 
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

実行します。
次なるエラーがこれでした。

FAILURE: Build failed with an exception.                                
 What went wrong:                                                      
 Execution failed for task ':app:processDebugResources'.                  
   A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   Android resource linking failed                                    
        /hoge/.gradle/caches/transforms-2/files-2.1/c49f6cd2b692fb3b2a354a1ed6c60c6b/play-services-ads-lite-19.7.0/AndroidManifest.xml:27:5-43:15: AAPT: error: unexpected element  found in . 

// (略) //

FAILURE: Build failed with an exception.
 Where:
 Build file '/usr/local/bin/flutter/.pub-cache/hosted/pub.dartlang.org/google_mobile_ads-0.11.0+3/android/build.gradle' line: 22
 What went wrong:
 A problem occurred evaluating root project 'google_mobile_ads'. 
   Failed to apply plugin [id 'com.android.internal.version-check']
   Minimum supported Gradle version is 6.5. Current version is 5.6.4. If using the gradle wrapper, try editing the distributionUrl in /usr/local/bin/flutter/.pub-cache/hosted/pub.dartlang.org/google_mobile_ads-0.11.0+3/android/gradle/wrapper/gradle-wrapper.properties to gradle-6.5-all.zip 

あれ、エラーメッセージが先ほどと同じ?
変わらずMinimum supported Gradle versionのエラーが出ていますね。
とりあえずキャッシュの中身(/usr/local/bin/flutter/.pub-cache/hosted/pub.dartlang.org/google_mobile_ads-0.11.0+3/android/gradle/wrapper/gradle-wrapper.properties )も5.6.4から6.5に変更しました。
(一回目のエラーからcacheを直せって書いてはあったんですけどね。。)

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

ここまででSDKとGradleのバージョン対応が完了しました。
最新ライブラリ導入時の主要なバージョン対応エラーが解決できたので、ここからは細かい調整になっていきます。
(意外とここからが予想外のエラーに手こずったりしがちではありますが…)

Could not determine the dependencies of task ‘:compileReleaseAidl’. SDK location not found.

次に出たエラーがこれです。

FAILURE: Build failed with an exception.                                
 What went wrong:                                                      
 Execution failed for task ':app:processDebugResources'.                  
   A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   Android resource linking failed                                    
        /hoge/.gradle/caches/transforms-2/files-2.1/c49f6cd2b692fb3b2a354a1ed6c60c6b/play-services-ads-lite-19.7.0/AndroidManifest.xml:27:5-43:15: AAPT: error: unexpected element  found in . 

// (略) //

FAILURE: Build failed with an exception.
 What went wrong:
 Could not determine the dependencies of task ':compileReleaseAidl'. 
   SDK location not found. Define location with an ANDROID_SDK_ROOT environment variable or by setting the sdk.dir path in your project's local properties file at '/usr/local/bin/flutter/.pub-cache/hosted/pub.dartlang.org/google_mobile_ads-0.11.0+3/android/local.properties'. 

SDKが見つからないから「:compileReleaseAidl」の依存関係が分からないよ、と言われています。
(何だこのエラーは。私にも分からないよ。)と思いながらネットで調べていると、我らの祖国「stack overflow」に次のような記述がありました。

The answer is simple. You have to just copy your local.properties file to the folder where project is stored and it will work like charm. But remember, it must be placed in the root folder where the project is stored.

https://stackoverflow.com/a/37365254

要するにlocal.propertiesファイルをプロジェクトのルートディレクトリに置け、ということみたいです(6年前の書き込みですが、、、)。
local.propertiesは開発時のローカル環境のビルドシステムなどのパスを記載しておくファイルです。
実際、エラーメッセージをよく読むと「ANDROID_SDK_ROOT変数を定義するsdk.dirのパスを指定しろ」と書かれており、この解決策は後者に当てはまるみたいですね。

でも私は今までの開発でlocal.propertiesを使ったことは無いし、それでも開発はできてるわけだし、とりあえず適当に空のlocal.propertiesファイルを作ればいいんじゃね?と思って作成し、プロジェクトルートに置いてみました。
この対応で正しいのかは分かりませんが、実行したらエラーメッセージが変化したので次に進みました。

D8: Cannot fit requested classes in a single dex file (# methods: 79416 > 65536). Error while merging dex archives: The number of method references in a .dex file cannot exceed 64K.

上記の作業をして実行すると、(何か色々ダウンロードが始まって、)次に出てきたエラーはこれでした。

Checking the license for package Android SDK Build-Tools 29.0.2 in /hoge/Library/Android/sdk/licenses
 License for package Android SDK Build-Tools 29.0.2 accepted.            
 Preparing "Install Android SDK Build-Tools 29.0.2 (revision: 29.0.2)".  
 "Install Android SDK Build-Tools 29.0.2 (revision: 29.0.2)" ready.      
 Installing Android SDK Build-Tools 29.0.2 in /hoge/Library/Android/sdk/build-tools/29.0.2
 "Install Android SDK Build-Tools 29.0.2 (revision: 29.0.2)" complete.   
 "Install Android SDK Build-Tools 29.0.2 (revision: 29.0.2)" finished.   
 注意:一部の入力ファイルは非推奨のAPIを使用またはオーバーライドしています。
 注意:詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。
 D8: Cannot fit requested classes in a single dex file (# methods: 79416 > 65536)
 com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
 The number of method references in a .dex file cannot exceed 64K.      

日本語で注意(Warning)が2つ出てきているのが気になりますが、とりあえずエラーとしては「メソッド数が65536(64K)を超えている」という内容ですね。
流石に私はそこまで大規模な開発をしているわけではないので、ここで言うメソッド数はフレームワークやライブラリの中身も含むのでしょう。
(64K超えて何があかんねん)と思いながら解決策を調べると、どうやら原因はdexファイルと呼ばれる実行形式ファイルでのメソッド参照制限のようで、これを解消するにはbuild.gradleで「multiDexEnabledをtrueする」か、「minSdkVersionを21以上にする」必要があるみたいでした。

「dexファイルを単一ではなく複数にすることでメソッド数の上限を引き上げる」という解決策が目に見えて分かる前者での対応でいい気がしますが、せっかくなので後者も対応しておきましょう(この記事の最初のエラーで16から19に引き上げたばっかりですが、、、)。
というわけで再びandroid/app/build.gradleを開きます。

defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "hoge"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        multiDexEnabled true
    }

実行します。

完了

完了です。

Launching lib/main.dart on natsuki in debug mode…
 Running Gradle task 'assembleDebug'…                                  
 Running Gradle task 'assembleDebug'… Done                        22.6s
 ✓ Built build/app/outputs/flutter-apk/app-debug.apk.
 Installing build/app/outputs/flutter-apk/app.apk…                 6.1s

無事にエラーが消え去り、アプリをビルドすることができました。

広告もちゃんと表示されていますね。
しかも、レイヤの最上層固定ではなくきちんとWidgetとしてアプリ内に組み込むことができています。
やったあ。

終わりに

新しく出るライブラリは総じてとっても便利なのですが、導入時のdependencies系のエラーと闘うのがしんどいですね。
しんどい理由は「中身の実装が全く分からないクセに大量のエラーが出てくるから」なのですが、かといって自力で実装するような無謀なことはできないので、ここは踏ん張るしかないのかもしれません。

私はエラーが出たらその内容をしっかり読み解くタイプなのですが、それも慣れるまではかなり重たい作業になってしまうので、少しでも誰かの力になれたらと思ってこの記事を書きました。

ちなみに、admobのID記述の部分でもエラーが出ましたが内容がかなりしょうもなかったのでこちらの記事にTipsとして記載しておきます。
あと全然関係ありませんがそろそろこのブログ、コードスニペットを貼れるブロックを導入しなきゃ。

タイトルとURLをコピーしました