Androidはワンツーパンチ 三歩進んで二歩下がる

プログラミングやどうでもいい話

Gradleのバージョンを3以上に上げた時に「Cannot set the value of read-only property 'outputFile' for ApkVariantOutputImpl_Decorated」というエラーが発生した時の対処方法

Android StudioでGradleプラグインを2系から3.0.1にアップデートしたところ、
次のようなエラーが発生しました。

Error:(160, 0) Cannot set the value of read-only property 'outputFile' for ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=debug, filters=[]}} of type com.android.build.gradle.internal.api.ApkVariantOutputImpl.

エラーメッセージに出てくる'outputFile'というのがread-onlyプロパティなのに
書き換えようとして怒られていますね。

'outputFile'はビルドしたapkファイルの名前を書き換える処理に使っている方が多いのではないでしょうか。

Gradleは3.0.0のメジャーアップデートで色々変わったようです。
この時に仕様変更した影響によるエラーでした。

Migrate to Android Plugin for Gradle 3.0.0 | Android Studio

f:id:sakura_bird1:20180119020157p:plain

これによると、Variant APIを使用してバリアントの出力をいじるのは
apkの名前変更みたいな簡単なもの以外出来なくなったようです。
outputFileのアクセスも出来なくなったので、
公式ドキュメントのようにファイルの名前を変更する箇所を書き換える必要があります。


私のアプリの例ですが、次のように書き換えました。

変更前

def toApkFile(originalFile) {
    def namePrefix = "PocketCarbo"
    def name = originalFile.name.replace(project.name,
            namePrefix + "-v" + android.defaultConfig.versionName)
    return new File(originalFile.parentFile, name)
}

android.applicationVariants.all { variant ->
    variant.outputs.each { output ->
        output.outputFile = toApkFile(output.outputFile)
        if (output.packageApplication.outputFile != output.outputFile) {
            output.packageApplication.outputFile = toApkFile(output.packageApplication.outputFile)
        }
    }
}

変更後

android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "PocketCarbo_v${android.defaultConfig.versionName}_${variant.name}.apk"
    }
}

書き方も簡略化してスッキリしましたが、
変更前、変更後のどちらもビルドすると
デバッグビルド時「PocketCarbo_v1.1_debug.apk」
リリースビルド時「PocketCarbo-v1.1-release.apk」
というような名前でapkファイルが作成されます。



エンジニアによるエンジニアのためのサイト始まる!!【teratail】