[英]SDK Project structure and building with Gradle?
隨着Android Studio成為Android開發的官方IDE,我想從Eclipse遷移一些項目。
我在多個Android示例應用程序中共享了Java庫項目。 在Eclipse中,我將Java庫項目稱為項目依賴項,但是當我分發時,Ant腳本生成庫jar並將其復制到Android libs文件夾。 我能夠輕松地調試我的代碼,而不會在分發時暴露庫源代碼或整個項目。
分發后的最終結果必須是帶有文檔和庫jar的壓縮示例應用程序。 有什么建議我如何在Android Studio中實現它?
經過長時間的搜索,我決定編寫自己的自定義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腳本和復制 - 在這里復制 - 但現在是時候遷移到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項目模板。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.