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 处理整合到一个步骤中,从而显着提升了编译性能。