2016-03-24 13 views
6

Recentemente ho analizzato segnalazioni di crash formano la mia app e hanno trovato diverse tracce di stack che punta a okhttpAndroid | Ottenere la versione OkHTTP Biblioteca in fase di esecuzione

mia app non dipende okhttp esplicitamente.

per quanto ne so okhttp versione dipende versione del sistema operativo Android, e okhttp libreria si è posta sul dispositivo

Per aiutare con la risoluzione dei problemi, ho deciso di registrare okhttp versione della libreria, e sembra che ho trovato diverse classi utili per questo

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

Giusto per fare in modo che non mi sbaglio ho preso com.android.okhttp.internal.http.HttpURLConnectionImpl modulo di classe stack trace e ho cercato di Class.forName esso - il successo

Inoltre ho notato che com.squareup.okhttp trasformati a com.android.okhttp sembra al accumulo di tempo, in modo del tutto ho provato tali varianti

  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") -> successo

Qualcuno può spiegare perché? Cosa mi sono perso?

Aggiornamento

ho tirato okhttp.jar dal mio dispositivo adb pull /system/framework/okhttp.jar ma contiene solo MANIFEST.MF

+0

in incidente rapporti si conosce la versione della vostra applicazione, e ammesso che abbiate almeno un controllo di versione semplice, dovresti sapere quale versione di okhttp è stata fornita con quella versione della tua app. – laalto

+0

La mia app non dipende da 'okhttp' in modo esplicito – CAMOBAP

risposta

1

da 4.xx Google sta utilizzando okhttp parte di SquareUp

/** 
* 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/

tutto dipende da dispositivo - che versione u usando perché api si sta evolvendo, u possibile utilizzare riflessioni, ma u bisogno di sapere che cosa campo os è su specifica API

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

per confrontare d versioni iffrent api usano: https://android.googlesource.com/platform/external/okhttp/

u può provare a inizio

System.getProperty("http.agent"); 

modificare:

tramite riflessioni

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

stesso come

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

e se volete disturbare:

  • ogni classe è trattata allo stesso modo -> come equals (senza controllo delle versioni - u può controllare unica grande minore numero magico - versione Java del compilatore dalla classe)
  • manifesto di/sistema/quadro/okhttp.jar non contiene proprietà versione

se volete classe okhttp.internal.Version poi:

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

conclusione: Se si vuole evitare crash di app dalla consegna libreria cambia propria versione della biblioteca e caricare le classi al volo o compilare con apk

+0

Che dire della soluzione per' okhttp 2.x'? E perché non posso accedere direttamente a "okhttp3.internal.Version"? – CAMOBAP

+0

@CAMOBAP - guarda la mia modifica – ceph3us

+0

grazie per l'aggiornamento, ma ho bisogno della versione, non di "Utente-Agente". Secondo il codice, so che 'Version.userAgent' contiene la versione attuale della libreria,' HttpURLConnectionImpl.defaultUserAgent' non – CAMOBAP

Problemi correlati