可以根据Android操作系统版本只加载的code特定行? [英] Possible to only load specific lines of code according to Android OS version?

查看:160
本文介绍了可以根据Android操作系统版本只加载的code特定行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有code,将只允许加载code。如果操作系统版本满足要求的简单的线条?

可以说,我有我的目标OS为2.2,但最小的SDK是3为Android 1.5这样​​即使我有一些code在我的项目不与1.5 compatable它仍然编译因为目标操作系统是2.2。无论如何,我想广告的一个特点,需要code,这不是在1.5 SDK,如果它在1.5手机加载会导致崩溃。有一个简单的事情是这样,我可以做什么?所以,我没有做出不能使用1.5的用户在整个应用程序?

 如果(Android操作系统==> 2.1){
            //在这里插入code要求2.1及更高版本}
        其他{
            //插入code这似乎是操作系统为< 2.1}
 

解决方案

是的,你可以做到这一点。事实上,有一种以上的方式。 (注:这个答案的只有Android的特定部分是你找出平台版本的方式)

假设类 X 的方法无效Y() 2.0版本开始,而不是之前。

要与出任何引入任何编译时依赖调用此方法的一种方法是使用反射来定位的方法,并调用引用就可以了。例如:

  X X = ...
如果(BUILD.VERSION.RELEASE.compareTo(2.0)GT; = 0){
    //(异常处理省略...)
    方法米= c.getClass()getDeclaredMethod(Y)。
    m.invoke(X);
}
 

另一种方法是创建一个版本兼容的API接口为您的应用程序是这样的:

  / **版本兼容性适配器API * /
接口COMPAT {
    无效DOY();
}

/ **适配器类版本1 * /
类CompatV1 {
    公共无效Y(X X){
       // 没做什么
    }
}

/ **适配器类第2版* /
类CompatV2 {
    公共无效Y(X X){
       x.y格式();
    }
}

//
// code实例相关的适配器为当前平台。
//
类<> compatClass;
//(异常处理略)
如果(BUILD.VERSION.RELEASE.compareTo(2.0)小于0){
    compatClass =的Class.forName(... CompatV1);
} 其他 {
    compatClass =的Class.forName(... CompatV2);
}
//(异常处理略)
COMPAT COMPAT =(COMPAT)compatClass.newInstance();

//适配器对象可以绕过作为参数,包
//为单身或注射使用依赖注入。

//调用x.y格式()如下:

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

第二个版本看起来有点重量级的,但它有一个动态(慢,非类型安全)code执行只有一次的优势,并且该版本的具体code从隔离其余的code。在现实生活中,你可能会提出一些方法插入适配器接口。

此方法需要更多的思考,制定出如何设计兼容的API,以便将彻底隔离的版本依赖关系的code中的其余部分。您还可能有修改适配器的API,并为每一个新的(不兼容)的主要版本创建新的适配器类。

最后,如果您需要调整使用类或方法的的移除的在新版本较旧版本带来的平台API的变化,那么你就需要编译你的各种适配器类(如 CompatV * 班)使用不同的Andr​​oid软件开发工具包。这会让你的构建过程较为复杂。


有关其他以对这个问题,阅读对Android的博客以下文章:

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}

解决方案

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:

这篇关于可以根据Android操作系统版本只加载的code特定行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆