Ric*_*ral 18 android dalvik dynamic-class-loaders gradle
根据Fred Chung在Android开发者博客上介绍Dalvik中的Custom Class Loading:
Dalvik VM为开发人员提供了执行自定义类加载的工具.应用程序可以从其他位置(如内部存储)或通过网络加载它们,而不是从默认位置加载Dalvik可执行文件("dex").
但是,没有多少开发人员需要进行自定义类加载.但那些按照博客文章中的说明进行操作的人可能会在使用Gradle(Google I/O 2013中引入的Android新构建系统)模仿相同行为时遇到一些问题.
究竟如何调整新构建系统以执行与旧(基于Ant)构建系统相同的中间步骤?
Ric*_*ral 27
我的团队和我最近在我们的应用程序中达到了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
Run Code Online (Sandbox Code Playgroud)
我们需要上面的代码,因为虽然示例是一个单独的Java项目,但我们仍然需要使用Android SDK中的组件.我们稍后还需要一些其他属性......所以,在主项目的build.gradle中,我们有这种依赖:
dependencies {
compile files("${androidSdkDir}/platforms/android-${compileSdkVersion}/android.jar")
}
Run Code Online (Sandbox Code Playgroud)
我们还简化了此项目的源集,这可能对您的项目来说不是必需的:
sourceSets {
main {
java.srcDirs = ['src']
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,我们将内置jar任务的默认配置更改为仅包含classes.dex文件而不是所有.class文件:
configure(jar) {
include 'classes.dex'
}
Run Code Online (Sandbox Code Playgroud)
现在我们需要有一个新任务,它将把所有.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}"
}
}
Run Code Online (Sandbox Code Playgroud)
另外,请确保在build.gradle文件中的某处(通常位于顶部)进行以下导入:
import org.apache.tools.ant.taskdefs.condition.Os
Run Code Online (Sandbox Code Playgroud)
现在我们必须让jar任务依赖于我们的dexClasses任务,以确保在最终的.jar文件组装之前执行我们的任务.我们用一行简单的代码来做到这一点:
jar.dependsOn(dexClasses)
Run Code Online (Sandbox Code Playgroud)
我们已经完成了......只需使用通常的assemble任务调用Gradle,最后的.jar文件${buildDir}/libs/${archivesBaseName}.jar将包含一个classes.dex文件(除了MANIFEST.MF文件).只需将其复制到您的应用资产文件夹中(您可以随时使用Gradle自动执行此操作,但这超出了此问题的范围)并按照博客文章的其余部分进行操作.
如果您有任何疑问,请在评论中大声说出来.我会尽力帮助我.
| 归档时间: |
|
| 查看次数: |
6341 次 |
| 最近记录: |