Java Android |在运行时获取OkHTTP库版本
最近,我分析了应用程序中的崩溃报告,发现了几个指向Java Android |在运行时获取OkHTTP库版本,java,android,okhttp,Java,Android,Okhttp,最近,我分析了应用程序中的崩溃报告,发现了几个指向okhttp String okEngineVersion = System.getProperty("http.agent"); 我的应用程序不明确地依赖于okhttp String okEngineVersion = System.getProperty("http.agent"); AFAIKokhttp版本取决于Android操作系统版本,并且okhttp库本身放置在设备上 String okEngineVersion = Syste
okhttp
String okEngineVersion = System.getProperty("http.agent");
我的应用程序不明确地依赖于
okhttp
String okEngineVersion = System.getProperty("http.agent");
AFAIKokhttp
版本取决于Android操作系统版本,并且okhttp
库本身放置在设备上
String okEngineVersion = System.getProperty("http.agent");
为了帮助排除故障,我决定记录okhttp
library版本,看起来我找到了几个有用的类
String okEngineVersion = System.getProperty("http.agent");
为了确保我没有弄错,我采用了com.android.okhttp.internal.http.HttpURLConnectionImpl
类表单堆栈跟踪,并尝试class.forName
it-success
String okEngineVersion = System.getProperty("http.agent");
我还注意到,com.squareup.okhttp
转换为com.android.okhttp
在构建时看起来很像,所以我尝试了这样的变体
String okEngineVersion = System.getProperty("http.agent");
Class.forName(“com.android.okhttp.internal.Version”)
->java.lang.ClassNotFoundException
Class.forName(“com.squareup.okhttp.internal.Version”)
->java.lang.ClassNotFoundException
Class.forName(“okhttp3.internal.Version”)
->java.lang.ClassNotFoundException
Class.forName(“com.android.okhttp.internal.http.HttpURLConnectionImpl”)
->successString okEngineVersion = System.getProperty("http.agent");
更新
String okEngineVersion = System.getProperty("http.agent");
我已经从我的设备中提取了okhttp.jar,但是它只包含了4.xx版本中的
MANIFEST.MF
,google正在使用squareup的okhttp部分
/**
* This implementation uses HttpEngine to send requests and receive responses. This class may use
* multiple HttpEngines to follow redirects, authentication retries, etc. to retrieve the final
* response body.
*
* <h3>What does 'connected' mean?</h3> This class inherits a {@code connected} field from the
* superclass. That field is <strong>not</strong> used to indicate whether this URLConnection is
* currently connected. Instead, it indicates whether a connection has ever been attempted. Once a
* connection has been attempted, certain properties (request header fields, request method, etc.)
* are immutable.
*/
public class HttpURLConnectionImpl extends HttpURLConnection {
private String defaultUserAgent() {
String agent = System.getProperty("http.agent");
return agent != null ? Util.toHumanReadableAscii(agent) : Version.userAgent();
}
String okEngineVersion = System.getProperty("http.agent");
编辑:
String okEngineVersion = System.getProperty("http.agent");
通过反射
HttpURLConnection connection = (HttpURLConnection) new URL("http://google.com")
.openConnection();
Method method = connection.getClass().getDeclaredMethod("defaultUserAgent");
method.setAccessible(true);
String okEngineVersion = (String) method.invoke(connection, new Object[]{});
String okEngineVersion = System.getProperty("http.agent");
同
String okEngineVersion = System.getProperty("http.agent");
如果你想麻烦的话:
String okEngineVersion = System.getProperty("http.agent");
- 每个类都以相同的方式处理->作为相等(没有版本控制-u只能从类中检查magic minor major number-java编译器版本)
- /system/framework/okhttp.jar的清单不包含版本属性
String okEngineVersion = System.getProperty("http.agent");
File file = new File("/system/framework/okhttp.jar");
// using javaxt-core lib
Jar jar = new Jar(file);
jar.getVersion();
// load dex
DexFile dexfile = DexFile.loadDex(file.getAbsolutePath(),
File.createTempFile("opt", "dex", _context.getCacheDir()).getPath(), 0);
Enumeration<String> dexEntries = dexfile.entries();
ClassLoader systemClassLoader = DexClassLoader.getSystemClassLoader();
while (dexEntries.hasMoreElements()) {
String className = dexEntries.nextElement();
Class<?> aClass = systemClassLoader.loadClass(className);
}
File File=new文件(“/system/framework/okhttp.jar”);
//使用javaxt核心库
Jar=新的Jar(文件);
getVersion();
//加载索引
DexFile DexFile=DexFile.loadDex(file.getAbsolutePath(),
createTempFile(“opt”,“dex”,“_context.getCacheDir()).getPath(),0);
枚举dexEntries=dexfile.entries();
ClassLoader systemClassLoader=DexClassLoader.getSystemClassLoader();
while(dexEntries.hasMoreElements()){
String className=dexEntries.nextElement();
类aClass=systemClassLoader.loadClass(类名称);
}
结论:如果您希望避免库更改交付导致应用程序崩溃
自己版本的库,动态加载类或使用apk编译
String okEngineVersion = System.getProperty("http.agent");
在崩溃报告中,您知道应用程序的版本,并且假设您至少有一些简单的版本控制,您应该知道该版本的应用程序附带了哪个版本的okhttp。我的应用程序不依赖于
okhttp
明确说明okhttp 2.x
的解决方案是什么?为什么我不能直接访问okhttp3.internal.Version
?谢谢您的更新,但我需要的是版本,而不是User Agent
。根据代码,我知道Version.userAgent
包含实际的库版本,HttpURLConnectionImpl.defaultUserAgent
不包含t@CAMOBAP-所以通过反射版本获得field@CAMOBAP-是,如果您不知道如何使用反射,请参阅编辑,然后了解有关反射的更多信息谢谢您的回复,没有帮助,因为jar未包含单独放置的dex
文件odex