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

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

  • ¿Cómo acceder al contexto en un Interceptor?
  • Tienda de cookies persistente con okhttp 2 en Android
  • Subir archivo binario con okhttp de recursos
  • SocketTimeoutException actualización de Android
  • Causado por: java.lang.NoClassDefFoundError: Clase no encontrada usando el cargador de clase de arranque; No hay rastro de la pila disponible
  • Ninguna excepción de clase encontrada com.squareup.okhttp.logging.HttpLoggingInterceptor
  • SocketTimeoutException en Retrofit
  • Conexión cerrada por peer (Android 5)
  • Proxy transparente para probar las respuestas del servidor sin conexión en Android
  • OKhttp PUT ejemplo
  • El uso de la dirección IP para el nombre común en el certificado del servidor no funciona en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.