可以根据Android操作系统版本仅加载特定行的代码吗?

发布于 2024-09-16 00:52:06 字数 417 浏览 6 评论 0 原文

是否有一行简单的代码允许仅在操作系统版本满足要求时加载代码?

假设我的目标操作系统是 2.2,但 android 1.5 的最小 sdk 是 3,所以即使我的项目中有一些与 1.5 不兼容的代码,它仍然会编译,因为目标操作系统是 2.2。无论如何,我想广告一个功能,该功能需要 1.5 SDK 中没有的代码,并且如果在 1.5 手机上加载该代码会导致崩溃。我能做这样简单的事情吗?所以我不必让整个应用程序对 1.5 用户不可用?

 if (Android OS == >2.1){
            //Insert code here that requires 2.1 and up}
        else{
            //insert code that would appear is OS is <2.1}

Is there a simple line of code that would allow only loading the code if the OS version meets the requirements?

Lets say I have my target OS as 2.2 but the min sdk is 3 for android 1.5 so even if i have some code in my project that isn't compatable with 1.5 it will still compile since the target OS is 2.2. Anyway, I want to ad a feature that requires code that's not in the 1.5 SDK and will cause a crash if it's loaded on a 1.5 phone. Is there a simple thing like this that I can do? So i dont have to make the entire app not available to 1.5 users?

 if (Android OS == >2.1){
            //Insert code here that requires 2.1 and up}
        else{
            //insert code that would appear is OS is <2.1}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

撩心不撩汉 2024-09-23 00:52:06

是的,你可以这样做。事实上,方法不止一种。 (注意:此答案中唯一针对 Android 的部分是查找平台版本的方法。)

假设类 X 在 2.0 版本中具有方法 void y()以后,但不是之前。

在不引入任何编译时依赖项的情况下调用此方法的一种方法是使用反射来定位该方法并对其调用invoke。例如:

X x = ...
if (BUILD.VERSION.RELEASE.compareTo("2.0") >= 0) {
    // (exception handling omitted ...)
    Method m = c.getClass().getDeclaredMethod("y");
    m.invoke(x);
}

另一种方法是为您的应用程序创建一个版本兼容性适配器 API,如下所示:

/** Version compatibility adapter API */
interface Compat {
    void doY();
}

/** Adapter class for version 1 */
class CompatV1 {
    public void y(X x) {
       // do nothing
    }
}

/** Adapter class for version 2 */
class CompatV2 {
    public void y(X x) {
       x.y();
    }
}

// 
// Code to instantiate the relevant adapter for the current platform.
//
Class<?> compatClass;
// (Exception handling omitted)
if (BUILD.VERSION.RELEASE.compareTo("2.0") < 0) {
    compatClass = Class.forName("...CompatV1");
} else {
    compatClass = Class.forName("...CompatV2");
}
// (Exception handling omitted)
Compat compat = (Compat) compatClass.newInstance();

// The adapter object can be passed around as a parameter, wrapped
// as a singleton or injected using dependency injection.

// Invoke X.y() as follows:

X x = ...
compat.y(x);

第二个版本看起来有点重量级,但它的优点是动态(缓慢、非类型安全)代码仅执行一次,并且版本特定的代码与其余代码隔离。在现实生活中,您可能会将许多方法放入适配器接口中。

这种方法需要更多的思考,以弄清楚如何设计兼容性 API,以便将版本依赖性与其余代码完全隔离。您可能还需要修改适配器 API,并为每个新的(不兼容的)主要版本创建新的适配器类。

最后,如果您需要适应的平台 API 更改需要使用旧版本中的类或方法,而这些类或方法在新版本中已删除,那么您将需要编译各种适配器类(例如使用不同 Android SDK 的 CompatV* 类)。这将使您的构建过程变得更加复杂。


有关此问题的其他“问题”,请阅读 Android 博客上的以下文章:

Yes, you can do that. In fact there is more than one way. (Note: the only Android specific part of this answer is the way that you find out the platform version.)

Suppose that class X has method void y() in version 2.0 onwards, but not before.

One way to invoke this method with out introducing any compile time dependencies whatsoever is to use reflection to locate the Method and call invoke on it. For example:

X x = ...
if (BUILD.VERSION.RELEASE.compareTo("2.0") >= 0) {
    // (exception handling omitted ...)
    Method m = c.getClass().getDeclaredMethod("y");
    m.invoke(x);
}

Another way is to create a version compatibility adapter API for your application like this:

/** Version compatibility adapter API */
interface Compat {
    void doY();
}

/** Adapter class for version 1 */
class CompatV1 {
    public void y(X x) {
       // do nothing
    }
}

/** Adapter class for version 2 */
class CompatV2 {
    public void y(X x) {
       x.y();
    }
}

// 
// Code to instantiate the relevant adapter for the current platform.
//
Class<?> compatClass;
// (Exception handling omitted)
if (BUILD.VERSION.RELEASE.compareTo("2.0") < 0) {
    compatClass = Class.forName("...CompatV1");
} else {
    compatClass = Class.forName("...CompatV2");
}
// (Exception handling omitted)
Compat compat = (Compat) compatClass.newInstance();

// The adapter object can be passed around as a parameter, wrapped
// as a singleton or injected using dependency injection.

// Invoke X.y() as follows:

X x = ...
compat.y(x);

The second version looks a bit heavyweight, but it has the advantages that the dynamic (slow, non-type-safe) code is executed just once, and that the version specific code is isolated from the rest of the code. In real life, you would probably put a number of methods into the adapter interface.

This approach requires a bit more thought, to work out how to design the compatibility API so that it cleanly isolates the version dependencies from the rest of the code. You might also to have to revise the adapter API, and create new adapter classes for each new (incompatible) major release.

Finally, if the platform API changes that you need to adapt to entail using classes or methods in the older version that are removed in the newer version, then you will need to compile your various adapter classes (e.g. the CompatV* classes) using different Android SDKs. This will make your build processes rather more complicated.


For other "takes" on this problem, read the following articles on the Android Blog:

痴意少年 2024-09-23 00:52:06

请参阅 Android 的向后兼容性(使用 < a href="http://developer.android.com/reference/java/lang/reflect/package-summary.html" rel="nofollow noreferrer">反射)。

青萝楚歌 2024-09-23 00:52:06

您可以使用Build.VERSION.RELEASE进行检查,它为您提供Android系统的当前版本(1.5,1.6,2.1,2.2)

Build.VERSION

You can check with Build.VERSION.RELEASE, it gives you the current version of your android system (1.5,1.6,2.1,2.2)

There is more on Build.VERSION

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文