Android | Obtener la versión de la biblioteca OkHTTP en tiempo de ejecución

Recientemente he analizado los informes de okhttp mi aplicación y encontré varios rastros de pila que apunta a okhttp

Mi aplicación no depende de okhttp explícitamente.

AFAIK okhttp versión depende de la versión de Android OS, y okhttp biblioteca por sí mismo colocado en el dispositivo

Para ayudar con la resolución de problemas decidí registrar la versión de la biblioteca okhttp , y parece que he encontrado varias clases útiles para esto

  1. com.squareup.okhttp.internal.Version
  2. okhttp3.internal.Version

Sólo para asegurarse de que no me equivoqué tomé com.android.okhttp.internal.http.HttpURLConnectionImpl clase de forma de pila de seguimiento y trató de Class.forName it – el éxito

También me di cuenta de que com.squareup.okhttp transformado a com.android.okhttp ve como en tiempo de construcción, por lo que totalmente he intentado tales variantes

  1. Class.forName("com.android.okhttp.internal.Version") -> java.lang.ClassNotFoundException
  2. Class.forName("com.squareup.okhttp.internal.Version") -> java.lang.ClassNotFoundException
  3. Class.forName("okhttp3.internal.Version") -> java.lang.ClassNotFoundException
  4. Class.forName("com.android.okhttp.internal.http.HttpURLConnectionImpl") -> el éxito

¿Puede alguien explicar por qué? ¿Qué me perdí?

Actualizar

He sacado okhttp.jar de mi dispositivo adb pull /system/framework/okhttp.jar pero sólo contiene MANIFEST.MF

One Solution collect form web for “Android | Obtener la versión de la biblioteca OkHTTP en tiempo de ejecución”

De 4.xx google está utilizando okhttp parte de la cuadratura

 /** * 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(); } 

https://github.com/square/okhttp/blob/master/okhttp-urlconnection/src/main/java/okhttp3/internal/huc/HttpURLConnectionImpl.java

http://square.github.io/okhttp/

Todo depende del dispositivo – lo que la versión u u usando porque api está evolucionando, u puede utilizar reflexiones, pero u necesita saber qué campo está en api específico

Consulte https://github.com/square/okhttp/blob/master/CHANGELOG.md

Para comparar diferentes versiones de api usar: https://android.googlesource.com/platform/external/okhttp/

Puedes probar al principio

 System.getProperty("http.agent"); 

editar:

A través de reflexiones

  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[]{}); 

igual que

 String okEngineVersion = System.getProperty("http.agent"); 

Y si quieres molestarte

  • Cada clase es tratada de la misma manera -> como iguales (no versioning – u solo puede comprobar el número mayor mágico mayor – la versión del compilador java de la clase)
  • Manifesto de /system/framework/okhttp.jar no contiene propiedades de versión

Si u quiere okhttp.internal.Version clase entonces:

  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); } 

Conclusión: Si desea evitar el bloqueo de la aplicación de los cambios en la biblioteca entrega propia versión de la biblioteca y las clases de carga sobre la marcha o compilar con apk

  • Retrofit invoca el método failure () incluso cuando el código de estado de los encabezados es 200
  • Retrofit 2.0 archivo de múltiples partes que envía sendto falló: ETIMEDOUT (conexión agotada) error
  • ¿Hay un reemplazo para el RequestInterceptor en Retrofit 2?
  • ¿Cómo obtener la URL redireccionada de OkHttp3?
  • Android - Utilice OkHttp con Webview
  • Conexión cerrada por peer (Android 5)
  • RETROFIT & AUTH COOKIE
  • Set Cookie para Picasso
  • OkHttp 3 y HttpURLConnection
  • Android OkHttp InputStream java.IOException.closed
  • Causado por: java.lang.NoClassDefFoundError: Clase no encontrada usando el cargador de clase de arranque; No hay rastro de la pila disponible
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.