0

文档HttpResponseCache有一个部分:

使用早期版本

这个类是在 Android 4.0 (Ice Cream Sandwich) 中添加的。使用反射来启用响应缓存而不影响早期版本:

try {
    File httpCacheDir = new File(context.getCacheDir(), "http");
    long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
    Class.forName("android.net.http.HttpResponseCache")
        .getMethod("install", File.class, long.class)
        .invoke(null, httpCacheDir, httpCacheSize);
}
catch (Exception httpResponseCacheNotAvailable) {
}

您可以在关于 SO 的问题(例如此处)和网络上的示例中通过反射查看此调用。我还接管了包含这个确切片段的代码来设置缓存(包括注释,所以它可能只是 copypasta)。但是,我不太明白为什么你必须在这里使用反射。

通常,当我想使用在我定义的某个 API 级别添加的方法时minSdkVersion,我会使用以下模式:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
   // do something here
}

那么为什么这不是HttpResponseCache. 使用反射有什么好处?它当然不会增加我的代码的可读性。HttpResponseCache以这种方式使用反射时,实际上是否在 ICS 下工作?

编辑:我这里没有旧的 Android 设备,我的模拟器根本拒绝启动,所以我现在不能简单地测试它。也许它只是在没有反射的情况下可怕地崩溃。

4

2 回答 2

0

使用反射有什么好处?

首先,引用文档:

这个类是在 Android 4.0 (Ice Cream Sandwich) 中添加的。

“被添加”的意思是“被添加到Android SDK ”,而“冰淇淋三明治”的真正意思是基于其余 JavaDocs 的 Android 3.2(API 级别 13)。

但是,HttpResponseCache该类本身在框架中存在的时间更长,希望自 Android 1.0 以来给出了他们的建议。但是,该类被标记了@hide注解,因此在 API 级别 13 之前,它不能被应用程序直接使用。

您的 Java 版本保护块使用Build将避免直接在旧设备上引用此类。但是,它实际上也没有在旧设备上配置缓存。他们的方法适用于所有版本的 Android,并允许您配置缓存,因为该类从一开始就存在。

谷歌明确授权使用反射以这种方式获取隐藏的类或方法是相当罕见的,这就是为什么你在官方文档中不经常看到它的原因。

于 2014-04-23T13:59:36.063 回答
0

不幸的是,您的建议不适用于旧版本。思考以下问题。他们install(File, long)在新版本中添加了方法。但是调用这个方法的代码被打包到其他jar中。

现在您有了包含旧版本的 jarHttpResponseCache和调用它的新版本的 jar。如果你在那里写

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
   cache.install(file, number);
}

NoSuchMethodError即使 if 的表达式为假,也会被抛出。使用反射是一种丑陋但有用的技术来防止这种情况。

于 2014-04-23T14:00:48.937 回答