美文网首页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