gpt4 book ai didi

android - 使用 Gradle 在 Dalvik 中自定义类加载(Android 新构建系统)

转载 作者:IT王子 更新时间:2023-10-28 23:36:37 27 4
gpt4 key购买 nike

根据Custom Class Loading in Dalvik的介绍作者 Fred Chung 在 Android 开发者博客上:

The Dalvik VM provides facilities for developers to perform custom class loading. Instead of loading Dalvik executable (“dex”) files from the default location, an application can load them from alternative locations such as internal storage or over the network.

但是,没有多少开发人员需要进行自定义类加载。但是那些按照该博客文章中的说明进行操作的人可能会在使用 Gradle(Google I/O 2013 中引入的新的 Android 构建系统)模仿相同行为时遇到一些问题。

究竟如何调整新的构建系统以执行与旧的(基于 Ant)构建系统相同的中间步骤?

最佳答案

我和我的团队最近在我们的应用程序中达到了 64K 方法引用,这是 dex 文件中支持的最大数量。为了绕过这个限制,我们需要将部分程序分割成多个二级dex文件,并在运行时加载。

我们按照问题中提到的旧的、基于 Ant 的构建系统的博客文章进行操作,一切正常。但我们最近觉得有必要迁移到基于 Gradle 的新构建系统。

此答案并不打算用完整的示例替换完整的博客文章。相反,它将简单地解释如何使用 Gradle 来调整构建过程并实现相同的目标。请注意,这可能只是其中一种方式,也是我们目前在团队中的方式。这并不一定意味着它是唯一的方式。

我们的项目结构有些不同,这个示例作为一个单独的 Java 项目工作,它将所有源代码编译成 .class 文件,将它们组装成单个 .dex 文件,最后将单个 .dex 文件打包成.jar 文件。

开始吧……

在根 build.gradle 中,我们有以下代码来定义一些默认值:

ext.androidSdkDir = System.env.ANDROID_HOME

if(androidSdkDir == null) {
Properties localProps = new Properties()
localProps.load(new FileInputStream(file('local.properties')))

ext.androidSdkDir = localProps['sdk.dir']
}

ext.buildToolsVersion = '18.0.1'
ext.compileSdkVersion = 18

我们需要上面的代码,因为尽管该示例是一个单独的 Java 项目,但我们仍然需要使用 Android SDK 中的组件。稍后我们还将需要其他一些属性...所以,在主项目的 build.gradle 上,我们有这个依赖项:

dependencies {
compile files("${androidSdkDir}/platforms/android-${compileSdkVersion}/android.jar")
}

我们还在简化此项目的源代码集,这可能对您的项目不是必需的:

sourceSets {
main {
java.srcDirs = ['src']
}
}

接下来,我们更改内置的默认配置jar简单地包含 classes.dex 文件而不是所有 .class 文件的任务:

configure(jar) {
include 'classes.dex'
}

现在我们需要一个新任务,将所有 .class 文件实际组装成一个 .dex 文件。在我们的例子中,我们还需要将 Protobuf 库 JAR 包含到 .dex 文件中。所以我在这里的例子中包括了它:

task dexClasses << {
String protobufJarPath = ''

String cmdExt = Os.isFamily(Os.FAMILY_WINDOWS) ? '.bat' : ''

configurations.compile.files.find {
if(it.name.startsWith('protobuf-java')) {
protobufJarPath = it.path
}
}

exec {
commandLine "${androidSdkDir}/build-tools/${buildToolsVersion}/dx${cmdExt}", '--dex',
"--output=${buildDir}/classes/main/classes.dex",
"${buildDir}/classes/main", "${protobufJarPath}"
}
}

另外,请确保您在 build.gradle 文件的某处(当然通常在顶部)有以下导入:

import org.apache.tools.ant.taskdefs.condition.Os

现在我们必须制作 jar任务取决于我们的dexClasses任务,以确保在组装最终的 .jar 文件之前执行我们的任务。我们用一行简单的代码来做到这一点:

jar.dependsOn(dexClasses)

我们完成了...只需使用通常的 assemble 调用 Gradle任务和您的最终 .jar 文件 ${buildDir}/libs/${archivesBaseName}.jar将包含一个 classes.dex 文件(除了 MANIFEST.MF 文件)。只需将其复制到您的应用 Assets 文件夹中(您始终可以像我们所做的那样使用 Gradle 自动执行该操作,但这超出了本问题的范围),然后按照博文的其余部分进行操作。

如果您有任何问题,请在评论中留言。我会尽我所能提供帮助。

关于android - 使用 Gradle 在 Dalvik 中自定义类加载(Android 新构建系统),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18174022/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com