AndroidStudio 生成 library 上传 JCenter

1,366 阅读8分钟

憋了那么久,我们今天来发个大招。现在Android开发主流工具都变成了AndroidStudio了,我们引用第三方库也发生了一些变化,譬如我们使用了比较流行的图片加载库glide,使用方式就是在我们的build.gradle文件中添加glide的引用就可以使用了,然后AndroidStudio会自动帮我们下载它的库了,是不是非常方便,非常cool?

从eclipse转到android studio后最方便的转变莫过于对于jar包的引用,原先我们在eclipse中引用的jar需要先从某个地方下载下来然后放入到lib文件目录下,而在android studio中,虽然也能用这种方式,但是android studio支持了新的添加方式,那就是依赖,一句话就可以引用jar包,对于相应的jar包更新的话,那就更方便啦,只需改个数字即可。


只需要上面一行代码即可引入jar包了,现在我们就来学习一下其中涉及到的方方面面。

前言

其中就以我自己写的一个开源库citypicker作为例子来详细了解下如何编写这个库。

基本内容了解

library从哪里来?

先从这个简单的问题开始,我相信不是每个人都完全明白Android studio 是从哪里得到这些library的。莫非就是Android studio 从google搜索然后下载了一个合适的给我们?

呵呵,没那么复杂。Android Studio是从build.gradle里面定义的Maven 仓库服务器上下载library的。Apache Maven是Apache开发的一个工具,提供了用于贡献library的文件服务器。总的来说,只有两个标准的Android library文件服务器:jcenter 和 Maven Central。

jcenter
jcenter是一个由 bintray.com维护的Maven仓库 。你可以在这里看到整个仓库的内容。我们在项目的build.gradle 文件中如下定义仓库,就能使用jcenter了:

allprojects {
    repositories {
        jcenter()
    }
}

Maven Central
Maven Central 则是由sonatype.org维护的Maven仓库。你可以在这里看到整个仓库。不管是jcenter还是Maven Central ,两者都是Maven仓库

我们在项目的build.gradle 文件中如下定义仓库,就能使用Maven Central了:

allprojects {
    repositories {
        mavenCentral()
    }
}

除了两个标准的服务器之外,如果我们使用的library的作者是把该library放在自己的服务器上,我们还可以自己定义特有的Maven仓库服务器。Twitter的Fabric.io 就是这种情况,它们在maven.fabric.io/public上维护了一…

repositories {
    maven { url 'https://maven.fabric.io/public' }
}

然后在里面使用相同的方法获取一个library。

dependencies {
    compile 'com.crashlytics.sdk.android:crashlytics:2.2.4@aar'
}

gradle 如何获取library?

比如我们在 build.gradle输入如下代码的时候,这些库是如果奇迹般下载到我们的项目中的。

compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'

一般来说,我们需要知道library的字符串形式,包含3部分:

GROUP_ID:ARTIFACT_ID:VERSION

上面的例子中:

GROUP_IDcom.inthecheesefactory.thecheeselibrary

ARTIFACT_IDfb-like

VERSION:0.9.3

group id 定义了library的group。有可能在同样的上下文中存在多个不同功能的library。如果library具有相同的group,那么它们将共享一个group id。通常我们以开发者包名紧跟着library的group名称来命名,比如com.squareup.picasso。然后ARTIFACT_ID中是library的真实名称。至于VERSION,就是版本号而已,虽然可以是任意文字,但是我建议设置为x.y.z的形式,如果喜欢还可以加上beta这样的后缀。

下面是Square library的一个例子。你可以看到每个都可以很容易的分辨出library和开发者的名称。

dependencies {
  compile 'com.squareup:otto:1.3.7'
  compile 'com.squareup.picasso:picasso:2.5.2'
  compile 'com.squareup.okhttp:okhttp:2.4.0'
  compile 'com.squareup.retrofit:retrofit:1.9.0'
}

那么在添加了上面的依赖之后会发生什么呢?简单。Gradle会询问Maven仓库服务器这个library是否存在,如果是,gradle会获得请求library的路径,一般这个路径都是这样的形式:GROUP_ID/ARTIFACT_ID/VERSION_ID。比如可以在jcenter.bintray.com/com/squareu…oss.sonatype.org/content/rep…
下获得com.squareup:otto:1.3.7的library文件。

然后Android Studio 将下载这些文件到我们的电脑上,与我们的项目一起编译。整个过程就是这么简单,一点都不复杂。

我相信你应该清楚的知道从仓库上下载的library只是存储在仓库服务器上的jar 或者aar文件而已。有点类似于自己去下载这些文件,拷贝然后和项目一起编译。但是使用gradle依赖管理的最大好处是你除了添加几行文字之外啥也不做。library一下子就可以在项目中使用了。

aar文件为何物?

仓库中存储的有两种类型的library:jar 和 aar。jar文件大家都知道,但是什么是aar文件呢?

aar文件时在jar文件之上开发的。之所以有它是因为有些Android Library需要植入一些安卓特有的文件,比如AndroidManifest.xml,资源文件,Assets或者JNI。这些都不是jar文件的标准。

因此aar文件就时发明出来包含所有这些东西的。总的来说它和jar一样只是普通的zip文件,不过具有不同的文件结构。jar文件以classes.jar的名字被嵌入到aar文件中。其余的文件罗列如下:

- /AndroidManifest.xml (mandatory)
- /classes.jar (mandatory)
- /res/ (mandatory)
- /R.txt (mandatory)
- /assets/ (optional)
- /libs/*.jar (optional)
- /jni/<abi>/*.so (optional)
- /proguard.txt (optional)
- /lint.jar (optional)

可以看到.aar文件是专门为安卓设计的。因此这篇文章将教你如何创建与上传一个aar形式的library。

library上传jCenter

申请bintray账号

Bintray可以用Github账号登陆,很方便.


申请完账号号我们需要拿到用户名和apiKey,等会发布的时候需要用到,这在个人中心中可以获得:


配置项目和library

这里以我自己的一个项目“CityPickerView”为例,讲解如何进行配置,这里面的配置主要分为项目ProjectLibrary配置,需要特别注意!


Project配置

打开build.gradle (Project: citypicker)
这个文件,在里添加:

classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'

添加过后的全部文件为:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Library配置

  • 配置local.properties

打开项目目录下面的local.properties文件,在里面添加第一在bintray.com网站上面获得的用户名和APIKey。添加后的内容为:

## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Thu Jun 30 10:46:46 CST 2016
sdk.dir=D\:\\DevelopTool\\android-sdk
bintray.user=你的用户名
bintray.apikey=你的APIKey

  • 配置build.gradle (Module: citypickerview)
    配置build.gradle (Module: citypickerview)的内容比较多,我们来仔细看看。重要的地方我都加了注释。
apply plugin: 'com.android.library'

//添加以下两个插件
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'

//你的library版本号
version = "0.1.0"

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    //资源前缀
    resourcePrefix "liji_"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    //增加lint选项,不加的话下面上传到jCenter有可能会报错
    lintOptions {
        abortOnError false
    }

}

buildscript {
    repositories {
        jcenter()
    }

}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'

}

//你的library的地址
def siteUrl = 'https://github.com/crazyandcoder/citypicker'
def gitUrl = 'https://github.com/crazyandcoder/citypicker.git'
def issueUrl = 'https://github.com/crazyandcoder/citypicker/issues'

//这个蛮重要的,你上传到jCenter后一些文件存放的路径,如果不写或者写错了的话
//可以不会产生pom文件,后面上传到jCenter后会报错,这个问题我搞了一下午!
group = "liji.library.dev"
install {
    repositories.mavenInstaller {
        // POM.xml文件内容
        pom {
            project {
                packaging 'aar'
                // 添加描述,不重要
                name 'city picker'
                url siteUrl
                // 协议
                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                developers {
                    developer {
                        id 'liji' //your user ID
                        name 'liji' //your name
                        email 'lijiwork@sina.com' //your email
                    }
                }
                scm {
                    connection gitUrl
                    developerConnection gitUrl
                    url siteUrl
                }
            }
        }
    }
}
task sourcesJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier = 'sources'
}

task javadoc(type: Javadoc) {

    //增加编码,这行很重要,如果是windows系统,同时如果在代码中有中文的话,不加这行,上传会报错
    options.encoding="utf-8"
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}
artifacts {
    archives javadocJar
    archives sourcesJar
}
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
bintray {
    user = properties.getProperty("bintray.user")
    key = properties.getProperty("bintray.apikey")
    configurations = ['archives']
    pkg {
        //发布到Bintray的哪个仓库
        repo = "maven"
        //发布到Bintray上的名字
        name = "citypickerview"
        //项目描述
        desc = "city picker"
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        issueTrackerUrl = issueUrl
        licenses = ["Apache-2.0"]
        //标签
        labels = ['android']
        publish = true
        publicDownloadNumbers = true
    }
}

上传jCenter

通过以上几个步骤的设置,我们已经设置好了要上传的一些必须步骤,接下来通过两行命令即可上传:
这两个命令可以在android studio中的终端执行:



gradlew install

gradlew bintrayUpload

执行第一条命令的时候有可能会下载gradle,大概耗时不少时间,当时我测试的时候,消耗大概20分钟左右,看个人电脑的网速,第二条命令大概消耗10秒钟左右,很快的。

执行这两条命令的时候有可能会包各种莫名其妙的错误,大伙可以google一下。

经过上面的命令我们就把aar包上传到jCenter上面了,但是这个时候我们还不能通过dependencies 的方式引用,因为还没有执行最后一步操作:


点击“add to jCenter”然后输入一些描述信息即可,最后等待官方来确认就可以发布啦。具体时间6小时左右!

版本更新

当我们完成0.1.0版本后添加了新的功能,或者修改了bug,编程0.2.0后,这时候需要我们进行更新操作,那么该如何操作呢?其实很简单,只需要三步操作即可。

  1. 修改build.gradle中的版本号
    //你的library版本号,更新的时候修改这个版本号
    version = "0.2.0"
  1. 上传JCenter
gradlew install

gradlew bintrayUpload
  1. 使用新版本

从上图可以看出,我们已经更新成功了就可以直接引用0.2.0的版本了。


关于我

简书 www.jianshu.com/users/18281…

博客 crazyandcoder.github.io/

github github.com/crazyandcod…

欢迎加入轮子学习(android)交流群

群名称:轮子学习(android)
群 号:539175620