标签: JDK

Android 开发工具兼容性/版本搭配

由于几个月前电脑 CPU 烧了,被迫换了 M1 的 Mac Mini,所以整个开发环境重新搭建了一遍。趁这个机会,我想整理几个基础工具的版本搭配策略、兼容性、以及在 M1 芯片上的表现。对于版本搭配和兼容性的一些讨论不局限于当前使用的版本和平台。

下方提及的版本分别是:

  • Zulu JDK: 11.0.11
  • Kotlin: 1.5.21
  • Gradle: 7.1.1
  • Android Gradle Plugin ( AGP ): 7.0 & 7.1
  • Android Studio: Arctic Fox 2020.3.1 & BumbleBee 2021.1.1 Canary 6

JDK

自 AGP 7.0 起,JDK 11 便是*低要求。JDK 11 成为 LTS ( Long-term Support) 版本已经有将近 3 年历史( Sep 2018 ),自身经历了 12 个小版本( 11.0.12 )的迭代目前相对成熟了。作为对比,上一个 LTS 的 JDK 8 2014 年发布,已经陪着我们走过了 7 年时光和 300 个小版本迭代。事实上作为 Android 开发者,即便目前项目是 Java 为主的情况,一般 Language Level 也仅 target to 1.8 (一些 9-12 的特性 D8 、R8 有支持,Android 11 12 也有融入)。Android 官方虽然说不会放弃 Java,但实际上对 Kotlin 的支持确实更给力。

从这个角度来看,JDK 11 带来给我们的更多是:

  • Kotlin Compiler 、Gradle 、IDE 层面上性能的升级;
  • JDK 8 将停止维护的情况下( 3 年后),安全层面的持续保障;
  • 适应新的发布机制,每半年一个小版本,三年一个 LTS 大版本,减少历史包袱跑得更快;

而 JDK 的升级策略我认为是:

  • 保守派:如果不在意新语言特性,可以等每年 AGP 升级的情况来决定 JDK 的版本,因为 IDE 一般 bundle 了一个 JDK,Kotlin 编译器、Gradle 一直追着*新 JDK 并有不错的向下兼容——所以根据木桶原理等 AGP 升级了再升即可,目前看来 AGP 可能也只跟进比较稳定的 LTS 版本;
  • 激进派:Gradle 支持后即可测试;

在 M1 Mac 上,由于 Oracle 还未有的 ARM64 版本,所以目前主流的做法是安装 Azul 维护的 Zulu JDK11

%title插图%num

需要注意的是,常用的 JDK 管理工具 SDKMAN! 在我的测试中依旧跑在 Rosetta 2 的转译环境中。这会造成即便你是安装的 Zulu JDK11,通过 SDKMAN! 的脚本启动依然会显示 Gradle java 的进程跑在 Intel ABI 下。故目前建议从官网下载安装,等后续配套工具支持后再考虑切换。

%title插图%num

Kotlin

Kotlin 的版本搭配限制相对不多,一般我考虑三个点:

  • 有没有特别吸引人的新功能,比如刚放出稳定版的 Coroutine 、Flow,或者新版本 Kotlin Multiplatform Mobile 的更好支持等;
  • 用不用大迭代的*个版本,例如观察刚发布时的 1.4.01.5.0,这条其实广泛适用于各类 Library ;
  • Gradle 目前 bundle/test 的 Kotlin 的版本,例如*新的 7.1.1 stable 依旧是用的 1.4.31 的 Kotlin ( 7.2 RC 则跳到 1.5.21 了);

关于*后一点,如果使用的 Kotlin 版本和 Gradle bundle 的不一致,会出现如下 Warning:

w: Runtime JAR files in the classpath should have the same version. >These files were found in the classpath: … /Users/2bab/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.4.31/84ce8e85f6e84270b2b501d44e9f0ba6ff64fa71/kotlin-stdlib-jdk7-1.4.31.jar (version 1.4) /Users/2bab/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.5.21/2f537cad7e9eeb9da73738c8812e1e4cf9b62e4e/kotlin-stdlib-1.5.21.jar (version 1.5) /Users/2bab/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.21/cc8bf3586fd2ebcf234058b9440bb406e62dfacb/kotlin-stdlib-common-1.5.21.jar (version 1.5) w: Consider providing an explicit dependency on kotlin-reflect 1.5 to prevent strange errors w: Some runtime JAR files in the classpath have an incompatible version. Consider removing them from the

用一个简单的例子看下问题是怎么发生的:

plugins {
    id("com.android.application")
    // 没有指定版本,用的就是 Gradle bundle 的版本,
    // Gradle 7.1.1 对应的就是 Kotlin 1.4.31 的各种类库和编译工具
    kotlin("android") 
}

dependencies {
    // 而这里我们却用了 1.5.21 的*新版 Kotlin,就会出现如上问题
    implementation("org.jetbrains.kotlin:kotlin-stdlib:1.5.21")
}

解决起来也很简单:

plugins {
    id("com.android.application")
    // 手动指定版本
    kotlin("android") version "1.5.21"
}

Kotlin 官方的文档直接就演示了加版本号的写法。但是,这个版本是 Kotlin 基于 Gradle 测试通过,而 Gradle 自身还没有基于它测试过并打包进去(见 Gradle 部分的配图),若出现了问题可能难以解决

所以我推荐的升级策略是:

  • 保守派:等 Gradle 升级的时候再升级,例如 1.5.0 到 1.5.21 中间仅隔了两个月,Gradle 就跟进了;
  • 激进派:有实用的新功能或者大版本迭代后的*个补丁版本就升。

Gradle

前面提到 Kotlin 的官方文档解释了各类和 Gradle 配合兼容的情况,反过来 Gradle 这边也有一个标明了 Java 、Kotlin 、Android 等各语言和平台的支持文档。

%title插图%num

像前面提到的 Java 版本支持,Kotlin 版本支持在这里便一目了然。除了 Kotlin 的支持会稍落后一两个月,其他工具的*新版本兼容都不成问题。而 Gradle 自身的向下兼容我觉得还不错,我基本上每个版本都升级。而上层的 AGP DSL,特别是老版本,则挺经常有大改动(好在 7.0 后终于强多了)。

所以我推荐的升级策略是:

  • 保守派:根据 AGP 的文档按*低版本进行升级(详见下图),例如 AGP 4.2.0+ 对应 Gradle 6.7.1+;
  • 激进派:每个补丁版本(x.y.1/2/3)或者每个版本都升( Gradle 没有 -betaX 的版本习惯,一般就是 Nightly 和 RC )。

%title插图%num

另外,Gradle 7.0 后的版本原生支持了 M1,我个人的使用体验还不错。

Android Gradle Plugin

AGP 的版本搭配限制我们在前面基本都介绍完了,以 7.0 为例,我们来看官方 Release Note 的兼容说明:

%title插图%num

额外补充一点:从 AGP 7.0 起,其版本会同步 Gradle 的 major 版本,严格遵守 Semantic Versioning 体系(之前同步的是 AS 的版本)。也即 AGP 7.x 会适配 Gradle 7.x 的版本。不过 AGP 的发布时间依旧是随着 AS 一起发布,并且目前来看其 alpha/beta 的数字是跟随 AS 的,所以其实可以当成三者形成了某种默契的同步机制。

所以我推荐的升级策略是:

  • 保守派:随 AS 正式版升级(或适当跳过*个大版本更迭);
  • 激进派:每个版本都升,或从 alpha/beta 开始升级,例如要做 Gradle 插件适配。

Android Studio

AS 基本上没有什么搭配限制,只要你用的之前正式版的 AGP,AS 就可以向下兼容。我推荐的升级策略是:

  • 保守派:适当跳过*个大版本更迭;
  • 激进派:每个版本都升,或从 alpha/beta 开始升级,例如要做 IDE 插件适配或者对 Compose 、调试工具新功能等有需求的。

另外,由于 AS 基于的 IDEA 社区版二次开发,整体稳定性、新特性支持的速度都不如 IDEA Ultimate,例如 Gradle 的 nesting Composite Build 目前就不在 AS 支持范围,见该 issue。

*后,自 Arctic Fox 2020.3.1 起,AS 原生支持了 M1,但如果想有更流畅的体验,我认为 BumbleBee 2021.1.1 Canary 效果更好一些。

IDEA

IDEA 的主要搭配限制来自于 Android Plugin ( Android IDE 插件)的版本适配。一般来说,在 AS 新的正式版本发布之后,下一个 IDEA 的正式版本就会带上该新版插件,从而对 Android 开发包括 AGP 做支持。

%title插图%num

偶尔也有等比较久的时候,比如今年 AS&AGP 4.2 在 4 月发布,而直到 7 月 IDEA 2021.2 发布时,才更新了 Android Plugin,官方的说法是 Google 放出 AGP 4.2 的源码时间晚了些,导致没赶上 2021.1 的版本。

我推荐的升级策略是:

  • 保守派:仅升级正式版本;
  • 激进派:从 EAP 或 RC 开始升级,例如会获得比较好的 Kotlin 支持、更早的 AGP 支持,以及 M1 平台的优化等。

*后,2021.2 也是让我在 M1 感觉终于不再有什么卡顿的版本了。

总结

我自己由于使用 M1 的平台 + 适配一些 Gradle Plugin,经常会使用 beta 甚至 alpha 的 AGP (作为 Runtime 的 library ),配合*新的 IDEA Ultimate 开发起来还是挺顺手。

而公司项目,现阶段 x86 平台我觉得可以使用如下配置,ARM M1 则根据上文调整对应的工具版本:

  • JDK 11 (由于 AGP 升了迟早要升级)
  • Gradle 7.1.1 ( 7.2 支持 1.5.21 后可以升级)
  • Kotlin 1.4.31
  • AGP 4.2.2 ( 7.0 稳定了新版的 Variant API,马上 7.1 也稳定新版的 DSL,不需要 Compose 的话可以观望观望)
  • AS 4.2.2 (不需要 Compose 的话可以观望观望)
  • IDEA 2021.2

在linux服务器中查看tomcat和jdk的版本

1.先连接linus服务器

2.ps -ef | grep 'tomcat' 查看tomcat所在位置
%title插图%num

3.进入需要查看的tomcat路径的bin目录 sh version.sh 即可查看 %title插图%num

4.Server version tomcat版本 :Apache Tomcat/7.0.53 JVM Version jdk版本:1.7.0_79

Gradle打包失败处理

为什么标题这么诡异,其实主要是同一个问题导致的。*近项目Unity版本从5.6.4升级到了Unity2017.4.7版本,然后使用Gradle打包,发现失败,提示这个错误CommandInvokationFailure: Gradle build failed。如下图:

%title插图%num
刚开始还是以为版本问题导致,换成不用Gradle打包,成功,但这没什么卵用,因为项目这边需要出AAR包(也就是所谓的母包),所以这个问题一定要解决,然后各种查,得到好几个方案:
1.更改jdk版本,改成JDK 1.8.161。
2.更改android的SDK版本,改成SDK 25.2.5。

%title插图%num
3.更改gradle版本, 改成Android plugin version 2.3.0和Gradle version 4.0.1。

%title插图%num
4.删除StreamingAssets的文件,使得数量不要超过250个。

%title插图%num
折腾了一天,下载JDK,下载AndroidSDK,下载Gradle版本,然后打包测试,发现前3个方案根本没有用,都快要*望了,然后试*后一个方案,成功解决了。为了测试苹果有没有这个问题,也打了个包测试下,苹果没有问题,估计这是Gradle的bug了。
但是因为首包资源需要放在StreamingAssets中,所以这个问题还需要解决,解决方案就是打成一个zip包,解压就行,但因为有lua代码,大佬说会有mono内存增加的问题,需要把lua的ab包拷贝到持久化目录中,但因为Unity中是只读的,所以需要在java处理。刚好之前写了个Utility的jar包获取CPU信息,继续在上面加个接口。参考了下这篇大佬的文章https://segmentfault.com/a/1190000004849884。

Java这边的代码是这样的,只是返回一个是否成功的bool值:

public boolean CopyFile(Object object, String oldPath, String newPath) {
Log.v(“ZP”, “1111111”);
AssetManager assetManager = (AssetManager)object;
String[] filenames = null;
InputStream input=null;
FileOutputStream output = null;
boolean bIsNull = assetManager == null;
if(bIsNull)
Log.v(“ZP”, “Is Null”);
else
Log.v(“ZP”, “Is Not Null”);
try {
filenames = assetManager.list(oldPath);
Log.v(“ZP”, “filenames.length: ” + filenames.length);
if(filenames.length <= 0)
{
Log.v(“ZP”, “222222”);
File newFlie = new File(newPath);
if(!newFlie.exists()){
newFlie.createNewFile();
}
else
{
return false;
}
//将内容写入到文件中
input=assetManager.open(oldPath);
output= new FileOutputStream(newFlie);
byte[] buffer = new byte[1024];
int len = 0;
while((len=input.read(buffer))!=-1){
output.write(buffer, 0, len);
}
output.flush();
Log.v(“ZP”, “33333333”);
return true;
}
}catch(IOException e)
{
e.printStackTrace();
}finally{
try {
if(output != null)
{
output.close();
output = null;
}
if(input != null)
{
input.close();
input=null;
}
// if(assetManager != null)
// {
// assetManager.close();
// assetManager = null;
// }
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}

C#调用的代码是这样的,代码还是蛮清楚的,个人认为。

/// <summary>
/// 调用: AndroidUtility.CopyLuaFile(“test.unity3d”, Application.persistentDataPath + “/test.unity3d”);
/// </summary>
/// <param name=”oldPath”></param>
/// <param name=”newPath”></param>
/// <returns></returns>
public static bool CopyLuaFile(string oldPath, string newPath)
{
#if UNITY_ANDROID && !UNITY_EDITOR
var activity = new AndroidJavaClass(“com.unity3d.player.UnityPlayer”).GetStatic<AndroidJavaObject>(“currentActivity”);
var assetManager = activity.Call<AndroidJavaObject>(“getAssets”);
var javaClass = new AndroidJavaClass(“com.zp.utility.api”);
var javaObject = javaClass.CallStatic<AndroidJavaObject>(“instance”);
return javaObject.Call<bool>(“CopyFile”, assetManager, oldPath, newPath);
#endif
return false;
}

安装JDK和Eclipse

上篇的Android SDK下载安装及配置教程。

总结起来,Android开发环境搭建可以分为以下四步:

*步、安装JDK

第二步、安装Eclipse

第三步、下载并安装AndroidSDK;

第四步、为Eclipse安装ADT插件

今天再来补充一下安装JDK和Eclipse:

安装JDK
官网:http://www.Oracle.com/technetwork/Java/javase/downloads/index.html

按照以下步骤操作即可:

(1)点击图中箭头所指的任意一个都可以。

%title插图%num

(2)接受

%title插图%num

(3)找到适合自己电脑系统的JDK版本,点击下载

%title插图%num

(4)自己选择路径安装完,注:不可以保存在中文路径下。

(5)变量环境的设置:我的电脑/计算机——属性——高级系统设置——环境变量。

①、新建一个系统环境变量,变量名为JAVA_HOME,变量值为JDK的安装路径

%title插图%num

②、在系统变量中找到Path,将;%JAVA_HOME%\bin; %JAVA_HOME%\jre\bin添加到变量值后面

注:在变量的*末尾添加时,需要加上分号;

③、检测是否配置成功。打开命令行窗口,输入javac -version。安装成功则看到oracle JDK版本号,如下图所示:

%title插图%num

 

安装Eclipse
官网:http://www.eclipse.org/downloads/

1、下载Eclipse,选择EclipseIDE for Java EE Developers,根据自己的系统选择32位或者64位的安装包,

2、将下载好的安装包解压缩至自己想要的位置,得到如图效果:

%title插图%num

3、双击eclipse/eclipse.exe。自己选择工作空间存放位置,出现以下图标则安装成功,若无请检查步骤一JDK是否正确安装和配置。

%title插图%num %title插图%num

 

 

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速