自定义类加载在Dalvik的有摇篮(Android的新构建系统) [英] Custom Class Loading in Dalvik with Gradle (Android New Build System)

查看:226
本文介绍了自定义类加载在Dalvik的有摇篮(Android的新构建系统)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照在Dalvik的引进自定义类加载由Fred涌在Android开发者博客:

As per the introduction of Custom Class Loading in Dalvik by Fred Chung on the Android Developers Blog:

Dalvik虚拟机提供了用于开发人员进行自定义   类加载。而是装载的Dalvik可执行文件(DEX)的文件   默认的位置,应用程序可以从其他装载它们   地点,如内部存储或网络。

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.

然而,没有多少开发人员需要做的自定义类加载。但是,这些谁在该博客文章做,并按照指示,可能有一些问题,模仿与摇篮相同的行为,新的构建系统为Android在谷歌I / O 2013。

However, not many developers have the need to do custom class loading. But those who do and follow the instructions on that blog post, might have some problems mimicking the same behavior with Gradle, the new build system for Android introduced in Google I/O 2013.

可以究竟如何适应新的编译系统来执行相同的中间步骤如旧(基于Ant)构建系统?

How exactly one can adapt the new build system to perform the same intermediary steps as in the old (Ant based) build system?

推荐答案

我和我的团队最近达到了我们的应用程序,这是一个DEX文件,所支持的最大数量的64K方法引用。为了解决这个限制,我们需要分区计划的一部分分成多个二级DEX文件,并加载它们在运行时。

My team and I recently reached the 64K method references in our app, which is the maximum number of supported in a dex file. To get around this limitation, we need to partition part of the program into multiple secondary dex files, and load them at runtime.

我们遵循基于问题的时候,蚂蚁提到的博客文章,构建系统,一切都工作得很好。但我们最近觉得需要移动到新的构建系统,基于摇篮。

We followed the blog post mentioned in the question for the old, Ant based, build system and everything was working just fine. But we recently felt the need to move to the new build system, based on Gradle.

这答案并不打算用一个完整的例子更换充分的博客文章。相反,它会简单地解释如何使用摇篮到调整的构建过程,并实现了同样的事情。请注意,这可能只是一种方法做它,以及如何我们正在做我们的团队。这并不一定意味着它的的只有的方式。

This answer does not intend to replace the full blog post with a complete example. Instead, it will simply explain how to use Gradle to tweak the build process and achieve the same thing. Please note that this is probably just one way of doing it and how we are currently doing it in our team. It doesn't necessarily mean it's the only way.

我们的项目结构有点不同,这个例子可以作为一个单独的Java项目,该项目将编译所有的源$ C ​​$ C到.class文件,将它们组装成一个.dex文件,并完成,包单。 DEX文件转换成一个.jar文件。

Our project is structured a little different and this example works as an individual Java project that will compile all the source code into .class files, assemble them into a single .dex file and to finish, package that single .dex file into a .jar file.

让我们开始...

在根的 build.gradle 的我们有下面这段code定义一些默认值:

In the root build.gradle we have the following piece of code to define some defaults:

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

我们需要code以上,因为虽然这个例子是一个单独的Java项目,我们仍然需要使用组件从Android SDK。而我们也将需要一些其他属性以后......所以,关于主体工程的 build.gradle 的,我们有这个依赖性:

We need the code above because although the example is an individual Java project, we still need to use components from the Android SDK. And we will also be needing some of the other properties later on... So, on the build.gradle of the main project, we have this dependency:

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

我们还简化了这一项目,它可能没有必要为您的项目的源代码集:

We are also simplifying the source sets of this project, which might not be necessary for your project:

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

接下来,我们改变集结罐子的默认配置任务简单地包含的 classes.dex 的文件中所有的.class代替文件:

Next, we change the default configuration of the build-in jar task to simply include the classes.dex file instead of all .class files:

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

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

Now we need to have new task that will actually assemble all .class files into a single .dex file. In our case, we also need to include the Protobuf library JAR into the .dex file. So I'm including that in the example here:

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

现在我们必须使任务依赖于我们的 dexClasses 任务,以确保执行我们的任务之前的最后.jar文件进行汇编。我们做了一个简单的一行code:

Now we must make the jar task depend on our dexClasses task, to make sure that our task is executed before the final .jar file is assembled. We do that with a simple line of code:

jar.dependsOn(dexClasses)

和我们就大功告成了......这简直是与通常的组装任务,并最终.jar文件调用摇篮, $ {buildDir} /库/ $ {archivesBaseName}的.jar 将包含一个单一的 classes.dex 的文件(除了MANIFEST.MF文件)。只是复制到您的应用程序资产的文件夹(你总是可以自动与摇篮,因为我们所做的不过是出于对这个问题的范围),并遵循的博客文章的其余部分。

And we're done... Simply invoke Gradle with the usual assemble task and your final .jar file, ${buildDir}/libs/${archivesBaseName}.jar will contain a single classes.dex file (besides the MANIFEST.MF file). Just copy that into your app assets folder (you can always automate that with Gradle as we've done but that is out of scope of this question) and follow the rest of the blog post.

如果您有任何问题,就骂了意见。我会尽力帮助,尽我的能力。

If you have any questions, just shout in the comments. I'll try to help to the best of my abilities.

这篇关于自定义类加载在Dalvik的有摇篮(Android的新构建系统)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆