美文网首页android编译相关
Android编译App的Java版本问题

Android编译App的Java版本问题

作者: 乔伯 | 来源:发表于2019-12-03 16:53 被阅读0次

    Android编译App的Java版本问题

    前言

    最近遇到一个问题,在我开发的工程里边引入了一个新的模块,然后在编译App的时候出现了编译失败,显示的错误日志如下:

    AGPBI: {"kind":"error","text":"Invoke-customs are only supported starting with Android O (--min-api 26)","sources":[{}],"tool":"D8"}
    AGPBI: {"kind":"error","text":"Default interface methods are only supported starting with Android N (--min-api 24): void android.arch.lifecycle.DefaultLifecycleObserver.onCreate(android.arch.lifecycle.LifecycleOwner)","sources":[{}],"tool":"D8"}
    

    定睛一看,咦,这莫非是要我把最低支持提升到Android O(API 26),那可坏了,业务不允许啊。于是上网搜了一把,原来是因为Java编译的版本问题,只需要把Java的编译版本改到Java 1.8即可。

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    

    为什么?

    问题很顺利解决,但是为什么会出现这个问题呢?
    于是我顺着android.arch.lifecycle.LifecycleOwner这个类进去看

    /*
     * Copyright (C) 2017 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package android.arch.lifecycle;
    
    import android.support.annotation.NonNull;
    
    /**
     * A class that has an Android lifecycle. These events can be used by custom components to
     * handle lifecycle changes without implementing any code inside the Activity or the Fragment.
     *
     * @see Lifecycle
     */
    @SuppressWarnings({"WeakerAccess", "unused"})
    public interface LifecycleOwner {
        /**
         * Returns the Lifecycle of the provider.
         *
         * @return The lifecycle of the provider.
         */
        @NonNull
        Lifecycle getLifecycle();
    }
    

    这个类确实是使用了Java 1.8 的新特性,在interface中直接定义了默认方法。
    这个类来自于 android.arch.lifecycle:common-1.1.1.jar是被间接依赖进来的。

    依赖关系图

    所以问题找到了,我们的工程里边本来采用的suport库是26.1.0版本,但是因为新引入的模块里边依赖了viewpager,直接使用了28.0.0,由于Gradle的对传递依赖版本的策略,导致把整个工程里边对suport库的版本升级到了28.0.0,所以这个问题就出现了。

    后记

    那这就意味着所有把suport库升级至28.0.0版本的都将需要采用Java 1.8进行编译。
    另外由于suport库升级至28.0.0版本,需要配套编译的sdk版本需要升级至Android 9.0(API 28),所以这可能也是Android团队推动社区对新系统做适配的技巧吧。

    但是这里也提出了一个新的问题,编译都使用Java 1.8了,是不是Java的1.8的特性都可以使用了?

    通过查看文档 (无需翻墙)发现从Gradle 的Android 插件3.0.0开始就已经支持了Java 1.8 的语法了

    支持的 Java 8 语言功能和 API

    原理是采用了新的编译引擎来实现的


    采用 desugar 字节码转换的 Java 8 语言功能支持

    另外在Android插件3.4.0中默认启用了R8工具,R8 将脱糖、压缩、混淆、优化和 dex 处理整合到一个步骤中,从而显着提升了编译性能。

    3.4.0的行为变更

    相关文章

      网友评论

        本文标题:Android编译App的Java版本问题

        本文链接:https://www.haomeiwen.com/subject/obtcgctx.html