【问题标题】:Get list of dependencies runtime获取依赖项运行时列表
【发布时间】:2016-04-08 01:29:52
【问题描述】:

最近我在Android Dependencies 上做一些研究工作,一个问题一直萦绕在我的脑海。问题是我们可以使用 java 代码获取依赖列表吗?

例如我的 build.gradle 文件中的依赖项

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

现在如果我想在应用程序运行时获得这些依赖项的名称,我们可以得到它吗?

【问题讨论】:

  • 没有。构建完成后,您从依赖项中得到的只是类。

标签: android android-studio build.gradle build-dependencies


【解决方案1】:

不是真的。它们是编译时依赖项。在您编译的 APK 中,以下之间没有显着差异:

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

  • compile project(':facebook'),您在其中克隆了一个 GitHub 存储库或其他东西来为您提供本地库项目,而不是从存储库中引用工件

  • 在您编写的应用程序中有一堆带有 Facebook 名称和包的类(同上一堆资源)

如果您正在编写应用程序,并且您使用不同的构建类型和/或产品风格,并且您对每个都有不同的依赖项,您可以使用 BuildConfig 来检测您正在运行的构建变体。

如果您正在编写一个库,并且您想在运行时确定开发人员是否添加了某个依赖项,那么您能做的最好的事情就是四处探查该依赖项中是否存在某些内容以及它们是否符合您的期望。这方面的细节会因依赖而异(例如,查看 Play 服务是否存在将有一组硬编码检查;查看 Facebook SDK 是否存在将有一组单独的硬编码检查)。这不会区分我上面的三个项目符号,但这是你能做到的最好的。

【讨论】:

  • 是的,这就是我正在尝试做的事情,编写一个库并想知道其他依赖开发人员添加了什么。
【解决方案2】:

在@CommonsWare 的 cmets 中添加一些关于在运行时查找 jar 依赖项的代码

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

可以输出这样的东西,你可以得到jar列表:

Using classloader: sun.misc.Launcher$AppClassLoader@29453f44

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: sun.misc.Launcher$ExtClassLoader@266474c2

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

【讨论】:

  • main?那将适用于 java 应用程序,而不是 android 应用程序。
  • 是的,但同样的概念也适用。获取ClassLoader 并查看它包含的路径。然后检查父 ClassLoader 的路径。该代码没有特定于 java 应用程序或 android 的内容。 (main方法除外)
  • 并非如此,因为您所有的依赖项都打包在同一个 dex 文件中。你只会得到系统类路径,它不能回答 OP 的问题。
猜你喜欢
  • 1970-01-01
  • 2017-12-27
  • 2013-05-23
  • 2023-04-04
  • 2021-07-27
  • 2013-06-28
  • 1970-01-01
  • 2013-02-14
  • 2015-05-07
相关资源
最近更新 更多