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 的语法了

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

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