您是否宁愿使用测试Build.VERSION.SDK_INT或反射来测试存在?

时间:2013-07-03 13:50:44

标签: android compatibility android-version

这是所有Android程序员的问题:

在我的应用中使用旧的和新的API方法时,我发现了两种方法来处理不同的API方法。

  1. 中测试SDK_INT
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        holder.content.setBackground(background);
    } else {
        holder.content.setBackgroundDrawable(background);
    }
    
  2. 编写一个“Compat”类,它使用反射来测试方法的存在,如

    private static final Method sApplyMethod = findApplyMethod();
    
    private static Method findApplyMethod() {
        try {
            Class<?> cls = SharedPreferences.Editor.class;
            return cls.getMethod("apply");
        } catch (NoSuchMethodException unused) {
            // fall through
        }
        return null;
    }
    
    public static void apply(final SharedPreferences.Editor editor) {
        if (sApplyMethod != null) {
            try {
                sApplyMethod.invoke(editor);
                return;
            } catch (InvocationTargetException unused) {
                // fall through
            } catch (IllegalAccessException unused) {
                // fall through
            }
        }
        editor.commit();
    }
    
  3. 现在,后者正在接受卡洛斯·塞萨(Carlos Sessa)出版的一本名为“50个Android黑客”的好书。 我被告知,使用异常处理进行流量控制是一件坏事,而且没有做到。如果你可以测试某些东西,不要故意遇到异常处理。 因此,方法2不会被视为“干净”。

    但是:在移动设备上,这是首选方法吗?从长远来看哪一个更快?

    感谢您的所有意见!

1 个答案:

答案 0 :(得分:1)

  

这是首选方法吗?

恕我直言,使用Build

  

从长远来看哪一个更快?

Build

更重要的是,Build告诉您什么是支持,因为您正在阅读JavaDoc并根据该文档确定是否要执行某些操作。

公共Java类上有许多公共方法,其中的类在Android SDK中,但方法不是。那些在AOSP源代码中标记为@hide,在创建我们链接到的android.jar时,在创建JavaDocs等时被删除。这些代表“未准备好黄金时间”的方法在Android团队眼中,需要在框架内公开供内部使用。反射技术很乐意报告这些隐藏方法可供使用,即使:

  • 他们的方法签名可能与最终在SDK中发布的内容不同(参数,返回类型,例外),可能是由于Android团队更改或制造商更改

  • 这些隐藏方法的行为没有记录,因此可能与这些方法发布时记录的功能不匹配

我是一个很大的@Macarse粉丝,但这是我们不得不同意不同意的一个案例。