2016-01-04 24 views
11

Recentemente stavo facendo dei lavori di ricerca su Android Dependencies e una domanda mi è rimasta impressa nella mente. La domanda è possibile ottenere l'elenco delle dipendenze utilizzando il codice java?Ottieni l'elenco delle dipendenze runtime

Per esempio le dipendenze nel mio file build.gradle

dependencies { 
    compile 'com.google.android.gms:play-services:+' 
    compile 'com.facebook.android:facebook-android-sdk:4.1.0' 
} 

Ora, se voglio nome di quelle dipendenze, mentre l'applicazione è in esecuzione, possiamo ottenerlo?

+0

no. tutto ciò che si ottiene dalle dipendenze una volta completata la compilazione sono le classi. – njzk2

risposta

3

Non proprio. Sono dipendenze in fase di compilazione. Nella tua compilato APK, non v'è alcuna differenza significativa tra:

  • compile 'com.facebook.android:facebook-android-sdk:4.1.0'

  • compile project(':facebook'), dove si clonato un repo GitHub o qualcosa per dare un progetto di biblioteca locale in contrasto con riferimento a un manufatto da una repository

  • avere un gruppo di classi con il nome di Facebook e il pacchetto nella vostra app che hai scritto (idem un po 'di risorse)

Se si sta scrivendo l'app e si utilizzano diversi tipi di build e/o gusti di prodotto e si hanno dipendenze diverse per ciascuno, è possibile utilizzare BuildConfig per rilevare quale variante di build si sta eseguendo.

Se si sta scrivendo una libreria e si desidera determinare in fase di esecuzione se lo sviluppatore ha aggiunto una certa dipendenza, il meglio che si può fare è annusarlo per vedere se certe cose esistono da quella dipendenza e se corrispondono alle proprie aspettative. I dettagli per questo variano in base alla dipendenza (ad esempio, se i servizi di riproduzione esistono con una serie di controlli codificati, vedere se l'SDK di Facebook esiste con una serie separata di controlli codificati). Questo non farà distinzione tra i miei tre proiettili di cui sopra, ma è il migliore che sarà in grado di fare.

+0

sì, questo è quello che sto cercando di fare, scrivere una libreria e voler sapere quali altri sviluppatori di dependecy hanno aggiunto. –

0

Per mettere un po 'di codice a @ commenti di CommonsWare di trovare le dipendenze vaso in fase di esecuzione

import org.kohsuke.args4j.CmdLineParser; 

import java.net.URL; 
import java.net.URLClassLoader; 
import java.util.ArrayList; 
import java.util.List; 

public class RuntimeDependenciesExample { 

    public static void main(String[] args) { 
     // just to add some dependency for our list 
     CmdLineParser parser = null; 
     RuntimeDependenciesExample main = new RuntimeDependenciesExample(); 
     main.findRuntimeDependencies(); 
     main.checkSystemClassPath(); 
    } 

    private void checkSystemClassPath() { 
     System.out.println("System classpath:\n" + System.getProperty("java.class.path").replace(':', '\n')); 
    } 

    private void findRuntimeDependencies() { 
     ClassLoader classloader = Thread.currentThread().getContextClassLoader(); 
     do { 
      System.out.println("Using classloader: " + classloader.toString()); 
      URL[] urls = ((URLClassLoader) classloader).getURLs(); 
      List<String> jars = new ArrayList<>(); 
      for (URL url : urls) { 
       jars.add(url.getFile()); 
      } 

      printFiltered(jars); 
      classloader = classloader.getParent(); 
     } while (classloader != null); 
    } 

    private void printFiltered(List<String> jars) { 
     System.out.println("\nFiltered jar list:"); 
     for (String jarPath : jars) { 
      if (!jarPath.contains("jre") && !jarPath.contains("jdk")) { 
       System.out.println(jarPath); 
      } 
     } 
     System.out.println('\n'); 
    } 
} 

Potrebbe uscita una cosa del genere, che si potrebbe ottenere la lista vaso:

Using classloader: [email protected] 

Filtered jar list: 
/Users/someUser/dev/test-code/build/classes/main/ 
/Users/someUser/dev/test-code/build/resources/main/ 
/Users/someUser/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy-all/2.3.11/f6b34997d04c1538ce451d3955298f46fdb4dbd4/groovy-all-2.3.11.jar 
/Users/someUser/.gradle/caches/modules-2/files-2.1/args4j/args4j/2.32/1ccacebdf8f2db750eb09a402969050f27695fb7/args4j-2.32.jar 
/Applications/IntelliJ%20IDEA%2016%20EAP.app/Contents/lib/idea_rt.jar 


Using classloader: [email protected] 

Filtered jar list: 
/usr/local/Cellar/subversion/1.8.10_2/lib/libsvnjavahl-1.0.dylib 
/System/Library/Java/Extensions/MRJToolkit.jar 


System classpath: 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/charsets.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/deploy.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/cldrdata.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/dnsns.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/jaccess.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/jfxrt.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/localedata.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/nashorn.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/sunec.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/ext/zipfs.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/javaws.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/jce.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/jfr.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/jfxswt.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/jsse.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/management-agent.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/plugin.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/resources.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/rt.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/ant-javafx.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/dt.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/javafx-mx.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/jconsole.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/packager.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/sa-jdi.jar 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/lib/tools.jar 
/Users/someUser/dev/test-code/build/classes/main 
/Users/someUser/dev/test-code/build/resources/main 
/Users/someUser/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy-all/2.3.11/f6b34997d04c1538ce451d3955298f46fdb4dbd4/groovy-all-2.3.11.jar 
/Users/someUser/.gradle/caches/modules-2/files-2.1/args4j/args4j/2.32/1ccacebdf8f2db750eb09a402969050f27695fb7/args4j-2.32.jar 
/Applications/IntelliJ IDEA 16 EAP.app/Contents/lib/idea_rt.jar 
+0

'principale'? sarebbe per un'app java, non per un'app per Android. – njzk2

+0

Sì, ma vale lo stesso concetto. Prendi il 'ClassLoader' e guarda il percorso che contiene. Quindi controlla il genitore 'ClassLoader' per il suo percorso. Il codice non ha alcuna app java o android specifica. (eccetto il metodo principale) – JBirdVegas

+0

Non proprio, perché tutte le tue dipendenze sono confezionate nello stesso file dex. Avresti solo il classpath di sistema, che non risponde alla domanda dell'OP. – njzk2