解决JavaCompiler的警告

最近在Build的过程中注意到Gradle的log中有一个关于JavaCompiler的警告。
具体如下:

Configure project :App
WARNING: API ‘variant.getJavaCompiler()’ is obsolete and has been replaced with ‘variant.getJavaCompileProvider()’.
It will be removed at the end of 2019.
For more information, see https://d.android.com/r/tools/task-configuration-avoidance.
To determine what is calling variant.getJavaCompiler(), use -Pandroid.debug.obsoleteApi=true on the command line to display more information.

按照提示,可以给build包命令加上参数来查看更详细的信息,运行以下命令:

.\gradlew assembleDebug -Pandroid.debug.obsoleteApi=true

结果如下:

Configure project :App
WARNING: API ‘variant.getJavaCompiler()’ is obsolete and has been replaced with ‘variant.getJavaCompileProvider()’.
It will be removed at the end of 2019.
For more information, see https://d.android.com/r/tools/task-configuration-avoidance.
REASON: Called from: D:\StudioProjects3.5\MyProject\App\build.gradle:267
WARNING: Debugging obsolete API calls can take time during configuration. It’s recommended to not keep it on at all times.

看来问题是在这个 build.gradle 文件上面,对应的代码如下:

android.libraryVariants.all { variant ->
    variant.javaCompiler.options.encoding = 'UTF-8'
}

可以看出上面的 .javaCompiler 是不推荐使用了,我们可以通过按住 Ctrl+ 点击 libraryVariant 查看源码来确定这一点。此时会打开 LibraryExtension.java 文件,相应的方法说明如下:

    /**
     * Returns a collection of <a
     * href="https://developer.android.com/studio/build/build-variants.html">build variants</a> that
     * the library project includes.
     *
     * <p>To process elements in this collection, you should use the <a
     * href="https://docs.gradle.org/current/javadoc/org/gradle/api/DomainObjectCollection.html#all(org.gradle.api.Action)">
     * <code>all</code></a> iterator. That's because the plugin populates this collection only after
     * the project is evaluated. Unlike the <code>each</code> iterator, using <code>all</code>
     * processes future elements as the plugin creates them.
     *
     * <p>The following sample iterates through all <code>libraryVariants</code> elements to <a
     * href="https://developer.android.com/studio/build/manifest-build-variables.html">inject a
     * build variable into the manifest</a>:
     *
     * <pre>
     * android.libraryVariants.all { variant -&gt;
     *     def mergedFlavor = variant.getMergedFlavor()
     *     // Defines the value of a build variable you can use in the manifest.
     *     mergedFlavor.manifestPlaceholders = [hostName:"www.example.com"]
     * }
     * </pre>
     */
    public DefaultDomainObjectSet<LibraryVariant> getLibraryVariants() {
        return libraryVariantList;
    }

这个方法是用来返回 Library 项目的所有构件变体的,所以要找的方法应该在 LibraryVariant 接口里面了。

/** A Build variant and all its public data. */
public interface LibraryVariant extends BaseVariant, TestedVariant {

    /**
     * Returns the Library AAR packaging task.
     *
     * @deprecated Use {@link #getPackageLibraryProvider()}
     */
    @Nullable
    @Deprecated
    Zip getPackageLibrary();

    /**
     * Returns the {@link TaskProvider} for the Library AAR packaging task.
     *
     * <p>Prefer this to {@link #getPackageLibrary()} as it triggers eager configuration of the
     * task.
     */
    @Nullable
    TaskProvider<Zip> getPackageLibraryProvider();
}

没有直接看到 getJavaCompiler() 方法,继续查看父接口 BaseVariant。

/**
 * A Build variant and all its public data. This is the base class for items common to apps,
 * test apps, and libraries
 */
public interface BaseVariant {
    /**
     * Returns the Java Compilation task
     *
     * @deprecated Use {@link #getJavaCompileProvider()}
     */
    @NonNull
    @Deprecated
    JavaCompile getJavaCompile();

    /**
     * Returns the {@link TaskProvider} for the Java Compilation task
     *
     * <p>Prefer this to {@link #getJavaCompile()} as it triggers eager configuration of the task.
     */
    @NonNull
    TaskProvider<JavaCompile> getJavaCompileProvider();

总算找到了 getJavaCompiler() ,源码上也确实注明了这个方法被弃用了,推荐使用 getJavaCompileProvider().
观察这两个方法,发现返回类型不一样,getJavaCompilerProvider() 返回的是一个 TaskProvider。来看看这个接口是什么:

/**
 * Providers a task of the given type.
 *
 * @param <T> Task type
 * @since 4.8
 */
public interface TaskProvider<T extends Task> extends NamedDomainObjectProvider<T> {
    /**
     * Configures the task with the given action. Actions are run in the order added.
     *
     * @param action A {@link Action} that can configure the task when required.
     * @since 4.8
     */
    void configure(Action<? super T> action);

    /**
     * The task name referenced by this provider.
     * <p>
     * Must be constant for the life of the object.
     *
     * @return The task name. Never null.
     * @since 4.9
     */
    String getName();
}

这个接口提供了一个 configure 方法,可以传入一个 Action 去配置对应的 Task。这样我们就可以改一下之前的 build.gradle 文件了。

android.libraryVariants.all { variant ->
    variant.javaCompileProvider.configure {
        
    }
}

本来处理到这里的时候有点懵逼了,也没参数,接下来怎么处理?看着看着,感觉跟 Kotlin 的 apply 方法很像啊,那就试试看。之前的 TaskProvider 的泛型参数类型是 JavaCompile。那我们是不是可以直接调用这个 JavaCompile 类的方法呢?那就试试:

android.libraryVariants.all { variant ->
    variant.javaCompileProvider.configure {
        options.encoding = 'UTF-8'
    }
}

Sync一下,Success。警告也消失了。Android Gradle Plugin 废弃 getJavaCompiler 方法应该是出于设计或性能考虑,大家遇到这类警告,最好也是花点时间按照提示一步步处理。在这里给想学习Gradle的同学推荐一下《Android Gradle 权威指南》。这本书对各个知识点理解得非常透彻,看完收获很大。最后感谢看到这里的同学。拜拜。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值