简体   繁体   English

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

[英]How to manage multiple versions of same class file for different SDK targets?

This is for an Android application but I'm broadening the question to Java as I don't know how this is usually implemented. 这是针对Android应用程序的,但是由于我不知道通常是如何实现的,因此我将问题扩展到Java。

Assuming you have a project that targets a specific SDK version. 假设您有一个针对特定SDK版本的项目。 A new release of the SDK is backward incompatible and requires changing three lines in one class. 新版本的SDK向后不兼容,并且需要在一个类中更改三行。

How is this managed in Java without duplicating any code(or by duplicating the least amount)? 在Java中如何在不复制任何代码(或复制最少的代码)的情况下进行管理? I don't want to create two projects for only 3 lines that are different. 我不想为三个不同的行创建两个项目。

What I'm trying to achieve in the end is a single executable that'll work for both versions. 最后,我想要实现的是一个适用于两个版本的可执行文件。 In C/C++, you'd have a #define based on the version. 在C / C ++中,您将基于版本定义#define How do I achieve the same thing in Java? 如何在Java中实现同一目标?

Edit : after reading the comments about the #define, I realized there were two issues I was merging into one: 编辑 :阅读有关#define的评论后,我意识到有两个问题要合并为一个:

  • So first issue is, how do I not duplicate code ? 因此,第一个问题是,如何不重复代码? What construct is there that is the equivalent of a #define in C. 那里的构造等效于C中的#define
  • The second one is: is it possible to bundle everything in the same executable? 第二个是:是否可以将所有内容捆绑在同一可执行文件中? (this is less of a concern as the first one). (这与第一个问题无关)。

It depends heavily on the incompatibility. 这在很大程度上取决于不兼容。 If it is simply behavior, you can check the java.version system property and branch the code accordingly (for three lines, something as simple as an if statement). 如果只是简单的行为,则可以检查java.version系统属性并相应地分支代码(对于三行代码,就像if语句一样简单)。

If, however, it is a lack of a class or something similar that will throw an error when the class is loaded or when the code gets closer to execution (not necessarily something you can void reasonably by checking before calling), then the solution gets a lot harder. 但是,如果缺少类或类似的东西而在加载类时或代码接近执行时会引发错误(不一定是可以在调用之前通过检查合理地放弃的东西),那么解决方案将好多了 The notion of having a separate version is the cleanest from a code point of view, but it does mean you have to distribute two versions. 从代码的角度来看,拥有单独版本的概念是最干净的,但这确实意味着您必须分发两个版本。

Another solution is reflection. 另一个解决方案是反射。 Don't reference the class directly, call it via reflection (test for the methods or classes to determine what environment you are currently running in and execute the methods). 不要直接引用该类,而是通过反射来调用它(测试方法或类以确定您当前正在哪个环境中执行这些方法)。 This is probably the "official" approach in that reflection exists to deal with classes that you don't have or don't know you will have at compile time. 这可能是反映存在的“正式”方法,以处理您在编译时没有或不知道将要拥有的类。 It is just being applied to libraries within the JDK. 它仅适用于JDK中的库。 It gets very ugly very fast, however. 但是,它变得非常丑陋。 For three lines of code, it's ok, but doing anything extensive is going to get bad. 对于三行代码,这是可以的,但是做大量的事情都会变得很糟糕。

The last thing I can think of is to write common denominator code - that is code that gets the job done in both, finding another way to do it that doesn't trigger the problematic class or method. 我能想到的最后一件事是编写共同的分母代码-即可以同时完成这两项工作的代码,找到另一种方法来完成,而不会触发有问题的类或方法。

I would isolate the code that needs to be different in a separate class (or multiple classes if necessary), and include / exclude them when building the project for the different versions. 我会将需要不同的代码隔离在一个单独的类中(或在必要时使用多个类),并在为不同版本构建项目时包括/排除它们。

So i would have like src/java/org/myproj/Foo.java which is the common stuff, and then oldversion/java/org/myproj/Bar.java and newversion/java/org/myproj/Bar.java which is the different implementations of the class that uses changed api. 所以我想要src / java / org / myproj / Foo.java是常见的东西,然后是oldversion / java / org / myproj / Bar.java和newversion / java / org / myproj / Bar.java是使用更改的api的类的不同实现。

Then I either compile "src/java and oldversion/java" or "src/java and newversion/java". 然后我要么编译“ src / java和oldversion / java”,要么编译“ src / java和newversion / java”。

Possibly a similar situation, I had a method which wasn't available in the previous version of the JDK but if it was there I wanted to call it, I didn't want to force people to use the more recent version though. 可能是类似的情况,我有一个方法在JDK的先前版本中不可用,但是如果有,我想称呼它,但是我不想强迫人们使用最新版本。 I used reflection to look for the method, if it was there I called it, if it wasn't I didn't. 我用反射来寻找方法,如果有的话我就叫它,如果不是的话我就叫它。

Pretty hacky but might give you what you want. 蛮笨拙的,但可能会给您您想要的东西。

Addressing Java in general, I see two primary approaches. 总体上讲Java,我看到两种主要方法。

1). 1)。 Refactor the specific code to its own library. 将特定代码重构为其自己的库。 Have different versions of that library. 具有该库的不同版本。 Effectively your app is creating an abstaction above the different SDKs. 实际上,您的应用正在不同的SDK之上创建摘要。 Heavyweight for 3 lines of code, but perhaps quite reasonable for larger scale problems. 具有3行代码的重量级代码,但对于较大规模的问题而言可能很合理。

2). 2)。 Injection using annotation. 使用注解进行注入。 Write your own annotation processor to manage the appropriate injection. 编写自己的注释处理器来管理适当的注入。 More work, but maybe more fun. 工作更多,但可能会更有趣。

Separate changing code in different classes with the same interface. 使用同一接口将不同类中的更改代码分开。 Place classes in the same jar. 将类放在同一罐子中。 Use factory design pattern to instantiate one or another class depending on SDK version. 使用工厂设计模式根据SDK版本实例化一个或另一个类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在同一应用程序中使用不同版本的 class? - How to use different versions of a class in the same application? Java - 如何加载同一类的不同版本? - Java - how to load different versions of the same class? 如何在Ubuntu中管理不同版本的Java - How to manage different versions of Java in Ubuntu 我怎样才能有单独的 gradle 项目的调试和发布版本,它们可以引入相同 class 的不同版本? - How can I have separate debug and release versions of gradle project that pull in different versions of the same class? 使同一类的不同版本通用的方法 - Making a Method common for different versions of same class 支持同一 class 的多个版本的优雅方式? - An elegant way to support multiple versions of the same class? Java:动态加载同一类的多个版本 - Java: Dynamically Load Multiple Versions of Same Class 当不同的类加载器提供一个类的多个版本时,如何引用一个特定的版本? - When multiple versions of a class are made available by different class loaders, how can I reference a particular one? 将多个版本的类文件加载到JVM - load multiple versions of the class file to the JVM 如何包含同一依赖项的两个不同版本? - How to include two different versions of the same dependency?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM