Android Gradle 3.0.0-alpha2插件,无法设置只读属性“ outputFile”的值

我在用这个密码

applicationVariants.all { variant ->
variant.outputs.each { output ->
def SEP = "_"
def flavor = variant.productFlavors[0].name
def buildType =
variant.variantData.variantConfiguration.buildType.name
def version = variant.versionName
def date = new Date()
def formattedDate = date.format('ddMMyy_HHmm')
def newApkName = PROJECT_NAME + SEP + flavor + SEP + buildType + SEP + version + SEP + formattedDate + ".apk"
def file = new File(newApkName)
output.outputFile = file
}
}


当我构建新的 apk 时,要更改 apk 文件的名称,但是因为我使用了 Android Studio 3.0金丝雀2,所以出现了这个错误:
无法设置只读属性“ outputFile”的值... 。

43478 次浏览

As Android plugin 3.0 migration guide suggests:

  • Use all() instead of each()
  • Use outputFileName instead of output.outputFile if you change only file name (that is your case)

Example from the guide:

// If you use each() to iterate through the variant objects,
// you need to start using all(). That's because each() iterates
// through only the objects that already exist during configuration time—
// but those object don't exist at configuration time with the new model.
// However, all() adapts to the new model by picking up object as they are
// added during execution.
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}

Below code is working for me on android studio canary 3.0.0-alpha3

android.applicationVariants.all {
variant.outputs.all {
def newApkName
newApkName = "APPLICATION_NAME-" + defaultConfig.versionName + "-" + defaultConfig.versionCode".apk"
outputFileName = newApkName;
}
}

This change the apk file name

See below:

applicationVariants.all { variant ->
variant.outputs.all { output ->
def newApkName = applicationId + "-" + variant.versionName + "(" + variant.versionCode + ")" + ".apk";
outputFileName = new File("${project.projectDir}/../outputs/apks/" + variant.name, newApkName);
}
}

I founded gradle 3.0 is no longer work. source link

However, more complicated tasks that involve accessing outputFile objects no longer work. That's because variant-specific tasks are no longer created during the configuration stage. This results in the plugin not knowing all of its outputs up front, but it also means faster configuration times.

then I used command gradlew to compile project.and cpthe output apk to my specified path

In Execute shell, i putted below command.

./gradlew clean assembleDebug
cp $WORKSPACE/app/build/outputs/apk/debug/*.apk $WORKSPACE/JenkinsApk

After update to Android Studio 3.0.0 and use the new gradle, now, the output of apks will be distributed in directories by flavors name and build types.

This is the complete example of this question.

Only you have to paste in your gradle 3.0+ after productFlavours

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


def SEP = "_"
def flavor = variant.productFlavors[0].name
def buildType = variant.variantData.variantConfiguration.buildType.name
def version = variant.versionName
def versionCode = variant.versionCode
def date = new Date();
def formattedDate = date.format('ddMMyy_HHmm')


outputFileName = "${flavor}${SEP}${buildType}${SEP}${version}${SEP}${versionCode}${SEP}${formattedDate}.apk"
}
}

I had the same problem. Error "Cannot set the value of read-only property 'outputFile'....""

So what I did is changing the version of the Android Plugin Repository to 2.3.3 in the Project Structure window. It works now and the error desappearded.

Project Structure

Later, do Clean and Rebuild for the project and that's it

Hope this would be helpful for you.

This is a year and half since the question was asked but maybe this will help someone (like me) who discovers this post first. I believe the answer to change the file name and directory was answered here.

applicationVariants.all { variant ->
variant.outputs.all { output ->
def relativeRootDir = output.packageApplication.outputDirectory.toPath()
.relativize(rootDir.toPath()).toFile()
output.outputFileName = new File( "$relativeRootDir/release", newOutputName)
}
}