LoginSignup
9
4

More than 5 years have passed since last update.

Android apkやmappingファイルをコピーするgradleスクリプトのGradle3.3+で出る警告の対処

Last updated at Posted at 2019-02-21

前提

"apkコピータスク"をこんな感じで作っていました。

applicationVariants.all { variant ->
    if (variant.buildType.name.equals("release")) {
      variant.outputs.each { output ->
        if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {
          // Rename APK
          def versionCode = defaultConfig.versionCode
          def versionName = defaultConfig.versionName
          def date = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())
          def newName = "AppName_r${versionCode}_v${versionName}_${date}.apk"

          def publish = project.tasks.create("publishAll")

          // Move and Rename APK
          def task = project.tasks.create("publish${variant.name.capitalize()}Apk", Copy)
          task.from(output.outputFile)
          task.rename(output.outputFile.name, newName)
          task.into(deployTo)

          task.dependsOn variant.assemble
          publish.dependsOn task

          // Move ProGuard
          if (variant.buildType.minifyEnabled) {
              def copyTask = project.tasks.create("copy${variant.name.capitalize()}MappingText", Copy)
              def buildTypeName = variant.buildType.name
              copyTask.from(file("build/outputs/mapping/${buildTypeName}").path)
              copyTask.into(deployTo + "/mapping")

              copyTask.dependsOn variant.assemble
              task.dependsOn copyTask
          }
        }
      }
    }
  }

apkをリネームしてcleanされない別フォルダにコピー、さらにproguardのmapping関係ファイルもコピーするというよく見るやつです。

発端

AndroidStudio3.3に上げたら警告が出るようになりました。

WARNING: API 'variant.getAssemble()' is obsolete and has been replaced with 'variant.getAssembleProvider()'.

調べると、com.android.tools.build:gradleが3.3以上で出る警告のようです。

修正

修正1

メッセージは、variant.getAssembleは使えなくなったのでvariant.getAssembleProvider()を使えと言うことなので、早速次のように変えます。

   task.dependsOn variant.assembleProvider.get()

もう一箇所有るのでそちらも忘れずに。

修正2

1を処置してsyncすると、エラーメッセージが変わりました。

WARNING: API 'variantOutput.getPackageApplication()' is obsolete and has been replaced with 'variant.getPackageApplicationProvider()'.

packageApplication()なんて箇所無いし、困った・・・と思ったら調査方法が書いてありました。

To determine what is calling variantOutput.getPackageApplication(), use -Pandroid.debug.obsoleteApi=true on the command line to display a stack trace.

実行コマンドにパラメータ追加すれば良いようですが、AndroidStudioのsyncボタンだし・・・(gradlewコマンドたたくの面倒くさいし・・・)と思って調べたら、gradle.propertiesに追記すれば良いと分かりました。

gradle.properties
android.debug.obsoleteApi=true

これでsyncすると、エラーの行を示してくれます。
それで調べると、どうやら引っかかっているのはoutput.outputFileの記述の箇所のようでした。

かなり難航しましたが、こちらのページを参考に、何とか解決しました。
(※中国語は読めません。コードだけで何とか言わんとすることを解釈しました。プログラミング言語は世界共通!)

修正前
if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {

...

   task.from(output.outputFile)
   task.rename(output.outputFile.name, newName)
修正後
if (output.outputFileName.endsWith('.apk')) {

...

   def srcDir = new File(variant.packageApplicationProvider.get().outputDirectory,
                       output.outputFileName)
   task.from(srcDir)
   task.rename(output.outputFileName, newName)

outputFile.nameは、outputFileNameに置き換えるだけで良かったのですが、それ以外に少し手間取りました。

つまりoutput.outputFile(AndroidのGradlePluginのメソッドのようです)が内部でgetPackageApplication()している箇所があって、その実装を追っていって下さったのが先ほど紹介した中国語のページです。
内部の実装を表に引っ張ってきて解決した、という形です。

※StackOverflow等では、「この警告はGoogleが直すべき」と言っている意見もありました。
Googleの修正を待ち自分は変更しない、というスタンスも有りだと思います。

完成形

ついでにequalsはoperatorに変更できるよと親切に教えてくれたのでその通りに直しました。

applicationVariants.all { variant ->
    if (variant.buildType.name == "release") {
      variant.outputs.each { output ->
        if (output.outputFileName.endsWith('.apk')) {
          // Rename APK
          def versionCode = defaultConfig.versionCode
          def versionName = defaultConfig.versionName
          def date = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())
          def newName = "AppName_r${versionCode}_v${versionName}_${date}.apk"

          def publish = project.tasks.create("publishAll")

          // Move and Rename APK
          def task = project.tasks.create("publish${variant.name.capitalize()}Apk", Copy)
          def srcDir = new File(variant.packageApplicationProvider.get().outputDirectory,
                                            output.outputFileName)
          task.from(srcDir)
          task.rename(output.outputFileName, newName)
          task.into(deployTo)

          task.dependsOn variant.assembleProvider.get()
          publish.dependsOn task

          // Move ProGuard
          if (variant.buildType.minifyEnabled) {
              def copyTask = project.tasks.create("copy${variant.name.capitalize()}MappingText", Copy)
              def buildTypeName = variant.buildType.name
              copyTask.from(file("build/outputs/mapping/${buildTypeName}").path)
              copyTask.into(deployTo + "/mapping")

              copyTask.dependsOn variant.assembleProvider.get()
              task.dependsOn copyTask
          }
        }
      }
    }
  }

最後に、gradle.propertiesに書いたフラグ(android.debug.obsoleteApi=true)をコメントアウトしておきましょう。
ビルドに時間がかかるようになるので「常時書いておくな」と説明が出ています。

参考

リリースビルドタスクでproguard関連ファイルをコピーする

Android Gradle 3.0以上で出力するapkのファイル名を変更する

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4