如何为不同的 SDK 目标管理同一类文件的多个版本?

Posted

技术标签:

【中文标题】如何为不同的 SDK 目标管理同一类文件的多个版本?【英文标题】:How to manage multiple versions of same class file for different SDK targets? 【发布时间】:2010-12-13 11:08:48 【问题描述】:

这是针对 android 应用程序的,但我将问题扩大到 Java,因为我不知道这通常是如何实现的。

假设您有一个针对特定 SDK 版本的项目。新版本的 SDK 向后不兼容,需要在一个类中更改三行。

如何在不复制任何代码(或复制最少的代码)的情况下在 Java 中进行管理? 我不想只为不同的 3 行创建两个项目。

我最终想要实现的是一个适用于两个版本的单一可执行文件。在 C/C++ 中,您将拥有一个基于版本的 #define。我如何在 Java 中实现同样的功能?

编辑:在阅读了有关#define 的 cmets 后,我意识到我将两个问题合并为一个:

所以第一个问题是,我怎么不 重复代码?有什么结构相当于a #define 在 C 中。 第二个是:有没有可能 将所有东西捆绑在一起 可执行? (这不是一个 关注第一个)。

【问题讨论】:

请问您的具体问题是什么? 问题与 Android 应用程序的大屏幕支持和管理联系人以及 ADK 版本 1.5、1.6 和 2.0 之间的兼容性有关。但我的问题确实更笼统。 我认为#define 是一个预处理指令,所以你最终得到了两个 C++ 版本? 见***.com/questions/3459032/… 【参考方案1】:

这在很大程度上取决于不兼容。如果只是行为,您可以检查 java.version 系统属性并相应地分支代码(三行,就像 if 语句一样简单)。

但是,如果缺少类或类似的东西会在类加载或代码接近执行时引发错误(不一定是您可以通过在调用前检查合理地取消),那么解决方案变得更加困难。从代码的角度来看,拥有一个单独版本的概念是最简洁的,但这确实意味着您必须分发两个版本。

另一种解决方案是反射。不要直接引用该类,通过反射调用它(测试方法或类以确定您当前正在运行的环境并执行方法)。这可能是“官方”方法,因为存在反射来处理您在编译时没有或不知道您将拥有的类。它只是应用于 JDK 中的库。然而,它变得非常丑陋非常快。三行代码就可以了,但是做任何大范围的事情都会变坏。

我能想到的最后一件事是编写公分母代码 - 即可以在两者中完成工作的代码,找到另一种不会触发有问题的类或方法的方法。

【讨论】:

确实是尝试加载类会报错的情况。 最终选择了反思作为解决方案。【参考方案2】:

我会将需要不同的代码隔离在一个单独的类(或多个类,如有必要)中,并在为不同版本构建项目时包含/排除它们。

所以我想要 src/java/org/myproj/Foo.java 这是常见的东西,然后是 oldversion/java/org/myproj/Bar.java 和 newversion/java/org/myproj/Bar.java这是使用更改的 api 的类的不同实现。

然后我要么编译“src/java and oldversion/java”,要么编译“src/java and newversion/java”。

【讨论】:

好的,我该怎么做才能有一个可执行文件而不是 2 个? 在 android 中它是一个 APK,但出于所有实际目的,我们可以将其视为一个 jar。所以一旦我有了两个类文件,我该如何创建一个 JAR?我是否必须在代码中使用反射来加载一个或另一个?我是否在命令行上指定了某些内容? 我认为分发两个版本的应用程序是可以的,重点是避免分叉源。如果两个版本都需要包含在同一个可运行文件中,您要么需要在实例化类时显式获取正确的版本(这里,类应该有不同的名称,但实现一个公共接口),或者使用类加载器做一些技巧. (删除了我之前的回答,因为我误解了你的问题)。 (顺便说一句,在 C/C++ 中使用#define 也意味着你必须分发不同的版本)。【参考方案3】:

可能是类似的情况,我有一个在以前版本的 JDK 中不可用的方法,但如果它在那里我想调用它,但我不想强迫人们使用更新的版本.我使用反射来寻找方法,如果它在那里我调用它,如果不是我没有。

相当老套,但可能会给你你想要的。

【讨论】:

【参考方案4】:

在一般情况下处理 Java,我看到了两种主要方法。

1)。将特定代码重构为自己的库。具有该库的不同版本。实际上,您的应用正在不同的 SDK 之上创建抽象。 3 行代码的重量级,但对于更大规模的问题可能相当合理。

2)。使用注解注入。编写您自己的注释处理器来管理适当的注入。更多的工作,但也许更有趣。

【讨论】:

【参考方案5】:

在具有相同接口的不同类中单独更改代码。将类放在同一个 jar 中。根据 SDK 版本,使用工厂设计模式来实例化一个或另一个类。

【讨论】:

以上是关于如何为不同的 SDK 目标管理同一类文件的多个版本?的主要内容,如果未能解决你的问题,请参考以下文章

如何为类赋予类似语句的功能?

如何为同一主机的多个 gitlab 帐户使用多个 ssh 密钥[重复]

Angular 8:如何为同一组件的多个实例提供不同的服务实例

如何为不同的客户端在应用商店中管理相同iOS应用的不同版本

Solr Highlighting:如何为同一字段请求多个片段长度?

如何为不同的项目版本和管理 angularjs 组件