随着Android Studio成为Android开发的官方IDE,我想从Eclipse迁移一些项目。
我在多个Android示例应用程序中共享了Java库项目。 在Eclipse中,我将Java库项目称为项目依赖项,但是当我分发时,Ant脚本生成库jar并将其复制到Android libs文件夹。我能够轻松地调试我的代码,而不会在分发时暴露库源代码或整个项目。
分发后的最终结果必须是带有文档和库jar的压缩示例应用程序。有什么建议我如何在Android Studio中实现它?
答案 0 :(得分:0)
经过长时间的搜索,我决定编写自己的自定义gradle插件,但首先是:
项目结构如下:
+--------------------+ +---------------------+
|Workspace (Project) | |Distributed archive |
| | | |
| | | |
| +------------+ | | +---------------+ |
| +-+ SDK | | | | SDK Jar lib | |
| | +------------+ | | +---------------+ |
| | | | |
| | +------------+ +---------> +---------------+ |
| +-> Sample 1 | | | | SDK Javadoc | |
| | +------------+ | | +---------------+ |
| | | | |
| | +------------+ | | +---------------+ |
| +-> Sample 2 | | | | Sample source | |
| +------------+ | | +---------------+ |
| | | |
+--------------------+ | +----------------+ |
| | Sample APK | |
| +----------------+ |
| |
+---------------------+
所以我们有几个项目的工作区:一个用于 SDK(纯Java)和几个样本(Java或Android),这取决于它我们想分发一个存档包含:
在Eclipse中它很简单 - 一些依赖项,Ant脚本和copy-here,copy-there,但现在是时候迁移到Intellij和Android Studio了。这是我成功编写自定义Gradle脚本的尝试:
apply plugin: CustomProcessor
import com.android.build.gradle.AppPlugin
import com.android.build.gradle.LibraryPlugin
class CustomProcessor implements Plugin<Project> {
private Project mRoot;
private List<WrappedProject> mProjects = new ArrayList<>();
private File mDistribOutput;
class WrappedProject {
private final Project project;
private final Object android;
WrappedProject(Project project) {
this.project = project;
if (isLibrary()) {
this.android = project.plugins.getPlugin(LibraryPlugin)
project.logger.info "${project.name}: SDK (API) project detected."
} else if(isApplication()) {
project.logger.info "${project.name}: Demo (Sample) project detected."
this.android = project.plugins.getPlugin(AppPlugin)
} else {
project.logger.warn "${project.name}: No Android plugin detected."
this.android = null
}
}
public boolean isLibrary() {
return project.plugins.any { p -> p instanceof LibraryPlugin }
}
public boolean isApplication() {
return project.plugins.any { p -> p instanceof AppPlugin }
}
}
@Override
void apply(Project target) {
this.mRoot = target
this.mDistribOutput = new File(target.buildDir, "custom")
target.configure(target.allprojects) { module ->
module.afterEvaluate {
def wrapped = new WrappedProject(module)
mProjects.add(wrapped)
if (wrapped.isLibrary()) {
addSdkTasks(wrapped.project)
}
if (wrapped.isApplication()) {
addSampleTasks(wrapped.project)
}
}
}
}
void addSdkTasks(Object project) {
project.android.libraryVariants.all { variant ->
if (variant.name.equalsIgnoreCase("release")) {
Task t = project.task("generate${project.name.capitalize()}Javadoc", type: Javadoc, overwrite: true) {
description "Generates Javadoc for $project.name."
source = variant.javaCompile.source
ext.androidJar = "${project.android.sdkDirectory}/platforms/${project.android.compileSdkVersion}/android.jar"
classpath = project.files(variant.javaCompile.classpath.files) + project.files(ext.androidJar)
exclude '**/BuildConfig.java'
exclude '**/R.java'
failOnError = false
}
t.group = 'custom'
t = project.task("javadoc${project.name.capitalize()}", type: Jar, overwrite: true) {
description "Bundles Javadoc into a JAR file for $project.name."
classifier = "javadoc"
appendix = project.name
baseName = mRoot.name
version = project.version
from project.tasks["generate${project.name.capitalize()}Javadoc"]
}
t.group = 'custom'
t = project.task("jar${project.name.capitalize()}", type: Jar, overwrite: true) {
description "Bundles compiled .class files into a JAR file for $project.name."
baseName = mRoot.name
appendix = project.name
version = project.version
dependsOn: [project.tasks.assemble ]
from variant.javaCompile.destinationDir
exclude '**/R.class', '**/R$*.class', '**/R.html', '**/R.*.html'
}
t.group = 'custom'
}
}
}
void addSampleTasks(Object sample) {
Task t = sample.task(
"distribute${sample.name.capitalize()}",
dependsOn: [sample.tasks.assemble, ":sdk:jarSdk", ":sdk:javadocSdk"],
overwrite: true,
type: Zip
) {
baseName = mRoot.name
appendix = project.name
version = "v${mRoot.project(':sdk').getVersion()}_${getDate()}"
classifier = 'src'
from("${project.buildDir}/outputs/apk/") {
include '**-debug.apk'
into "apk"
}
from("${mRoot.project(':sdk').buildDir}/docs/javadoc") {
into "doc"
}
from("${mRoot.project(':sdk').buildDir}/libs") {
into "libs"
}
from("${mRoot.project(':sdk').buildDir}/libs") {
into "sample/app/libs"
}
from(sample.zipTree("${sample.rootDir}/sample.zip")) {
into "/"
}
from(sample.projectDir) {
exclude "build"
exclude "**.iml"
exclude "build.gradle"
into "sample/app"
}
}
t.group = 'custom'
}
static def getDate() {
def date = new Date()
def formattedDate = date.format('yyyyMMddHHmmss')
return formattedDate
}
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}
allprojects {
repositories {
jcenter()
}
}
要在Android Studio中将示例源生成为可打开的项目,我使用sample.zip
这是空的Android Studio项目模板。