【发布时间】:2012-04-18 15:33:09
【问题描述】:
我正在使用反射来调用我的 Android 应用程序的目标 API 级别之外的方法:
try {
Method m = Class.forName("android.content.Context")
.getDeclaredMethod("getExternalCacheDir");
Object result = m.invoke(this);
if (result instanceof File) {
Log.v("MyApp", "external cache: "
+ ((File) result).getAbsolutePath());
cacheDirectory = (File) result;
} else {
Log.v("MyApp", "non-file cache: " + result);
}
} catch (Exception e) {
// ...
}
我可以通过 Proguard 毫无问题地优化它,但它警告我:
Note: com.example.MyApp accesses a declared method 'getExternalCacheDir()' dynamically
Maybe this is library method 'android.content.Context { java.io.File getExternalCacheDir(); }'
Maybe this is library method 'android.content.ContextWrapper { java.io.File getExternalCacheDir(); }'
Maybe this is library method 'android.test.mock.MockContext { java.io.File getExternalCacheDir(); }'
Note: there were 1 accesses to class members by means of introspection.
You should consider explicitly keeping the mentioned class members
(using '-keep' or '-keepclassmembers').
这是一个实际问题,还是 Proguard 只是通知我一个潜在问题?
【问题讨论】:
-
对你来说没问题。它警告你不应该保护 Android 框架,因为重命名框架方法会破坏你的反射。
-
没错,我知道这种危险。提高 API 目标级别并使用
Build.VERSION.SDK_INT检查包围函数调用会是更好的做法。不幸的是,项目库用于遗留应用程序,并且被某种“不干涉”政策所笼罩。 -
嘿,原来库已经设置为 SDK 目标 8!我需要做的就是将检查包裹起来并用函数调用替换反射!