从零到一发布Android开源库

最近在Flipboard实习期间写了一个轮播工具,技术上没什么难点,不过动画效果还是不错的,决定改改代码写个库开源出去。项目地址:http://github.com/chengdazhi/DecentBanner,欢迎大家提Issue报Bug。由于国内有关发布开源库的文章与教程很少见,我就先挖个坑。

本文力求简明,希望大家可以很快学会如何把自己写的代码开源出去,并让全世界的开发者可以通过一句compile语句来使用。毕竟重点在于库本身,而发布只是必须的过程。

整个过程涉及以下几个工具:

  • Android Studio + Gradle : 用于将库独立成模块。

  • Bintray : Bintray是用于托管库代码的地方,也是将库发布到JCenter的工具。只有库发布到JCenter,在Gradle中才可以通过一句compile命令来集成。

  • Telecine : 用于给Android应用录屏。

过程分为以下几步:

  1. 将代码封装在一个module中。
  2. 通过gradle将代码上传到Bintray。
  3. 将代码托管到GitHub,并编写README,以及后续推广与维护。

下面以这三步为主线一步步将库开源出去。

封装代码

在这一部分中我们要把库的代码封装并生成aar文件。aar文件类似于jar,只不过由于Android还包含XML、Assets、JNI等等其他格式的文件,所以打包后的结果就是aar。

首先在Android Studio中点击File菜单,选择New->New Module,然后在弹出视图中选择Android Library,点击Next后填写库的名称。

new_module

我在这里填写decentbanner,然后在目录视图中就可以看到两个module了,一个是App的,一个是库的。(默认可运行的module名称为app,我在这里改成了demo)

project_structure

创建完新的module后就可以填充代码了,至于写什么组件倒没有关系。写好后,如果想在app module中使用新的module中的类,需要在app module下的build.gradle中添加依赖:

compile project(':yourmodulename') //冒号后是你的新module的名称

当你在app module下测试没有问题后,这一步就完成了。当然这里的重点在于库的代码,封装本身是没有难度的。

将库上传到Bintray

Bintray是一个可以托管Android库的平台,平时我们在gradle中通过一句compile命令就可以引用的库,都托管在JCenter上,而JCenter则由Bintray维护。我们在这个部分中要进行的操作分两步,一是将我们的代码上传到Bintray的Maven仓库中,二是将Maven仓库发布到JCenter。在这一部分中Gradle是核心,所以如果你哪个地方出了问题,我在这个部分末尾给出了几个gradle文件的GitHub地址可以供大家参考。

当你完成注册并登录到Bintray后,你会发现有九个仓库可供你使用,点View All后你会看到Maven选项。这里不需要进行任何操作,只需要知道我们要使用Maven进行上传即可。我们这里真正需要的是API Key,后面当我们在上传库时需要提供username和API key,具体在哪里后面再说。大家不妨先在网站里到处逛逛。

bintray_repos

Maven

首先我们因为要使用到Bintray和Maven的服务,我们需要在项目根目录下的build.gradle中添加两行classpath。具体的文档可以参考Bintray pluginMaven plugin

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

这里依赖的插件版本低于GitHub文档中的最新版本,因为我依赖最新版时发现Android Studio会报错,信息是库不兼容,如果你没有这个问题,当然还是最新版最好。在添加完classpath后,要在你的库module中依赖新的插件,只需将下面两行添加到库module目录中的build.gradle文件即可。

apply plugin: 'com.jfrog.bintray'
apply plugin: 'com.github.dcendents.android-maven'

Bintray在上传库时需要一个POM文件,而这个文件可以让Maven插件自动生成,但你还是需要给出groupId和version的值,只需要将下面这两行代码添加到库module的build.gradle中即可。

group = '你的库的包名' // 这里需要和真实包名对应,不能随便填写
version = '1.0.1' // 指定版本号

为了与Maven标准对应,你需要在库module的build.gradle中添加几个task,分别生成Jar,Javadoc和JavadocsJar,只需要将下面三个task代码添加到gradle文件即可。

task generateSourcesJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs //通过from函数指定代码源,这里是默认代码源
    classifier 'sources'
}

task generateJavadocs(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs //source指定了代码源
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

//这里dependsOn意为仅当generateJavadocs完成后才开始本task
task generateJavadocsJar(type: Jar, dependsOn: generateJavadocs) {         
    from generateJavadocs.destinationDir
    classifier 'javadoc'
}

为了将你生成的源代码和Javadoc Jar文件添加到Maven中,你需要将task添加到一个archive中,只需要向库module下的build.gradle中添加如下代码:

artifacts {
    archives generateJavadocsJar
    archives generateSourcesJar
}

Bintray

到这里我们已经配置好了Maven插件,现在需要配置Bintray插件。在编写代码前,我们需要提供username和API key,username就是你注册时填写的,如果你直接用GitHub登录,那么username就是GitHub的username。要找到API key,首先进入个人主页,即点击Bintray主页右上角的头像并点击Your Profile,然后点击头像右侧大大的Edit按钮,而后在左侧找到API Key选项即可。

bintray_apikey

我们在这里先将这两个值写在local.properties下,因为这种数据是不应该传到GitHub的。

bintray.user=your_username
bintray.apikey=your_apikey

而后我们继续在库module下的build.gradle中添加如下代码块,这里我直接贴了我的代码,方便大家参阅,请大家对具体的值进行修改。在这里有一个license属性,马上就要说到如何选择一个license。license只是声明别人在使用你的代码时的权限,不需要申请,选择之后直接在项目中添加一个相应的LICENSE文件即可。除此之外,

//需要在local.properties文件中取值
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

bintray {
    user = properties.getProperty("bintray.user")
    key = properties.getProperty("bintray.apikey")

    pkg {
        repo = 'maven'
        name = 'it.chengdazhi.decentbanner'

        version {
            name = '1.0.5-tuts'
            desc = "decent banner"
            released = new Date()
            vcsTag = '1.0.5'
        }
    }

    configurations = ['archives']
}

在选择License时,可以参考这张图,来自阮一峰老师的博文。刚才说过,选择License只是选择一种权利,选好之后可以直接添加就好。GitHub在创建Repo时可以快速添加License文件。

license

以上除了两行classpath写在根目录build.gradle,以及username和apikey写在local.properties下,其余修改的全部是库module下的build.gradle文件,完整文件可以参考我的源码。到这里我们完成了所有gradle的编写,现在我们需要进入Gradle Window视图,默认在Android Studio的右侧,处在最小化状态,找不到可以从菜单点击View->Tool Windows->Gradle调出。点击图标栏的Gradle图标。

gradle_window

输入install,点击OK。注意这里的Gradle project是你的库module。这时会执行Maven相关的task。

gradle_command

而后你的库module的build目录下会出现POM文件,AAR文件,源代码Jar文件和Javadocs Jar文件。

library_build

成功后再次点击Gradle图标,输入bintrayUpload并点击OK。执行成功后你的库就成功上传到Bintray了。注意以后每次更新库时需要更新版本号,不然会冲突,同时每次都需要顺序执行install和bintrayUpload。上传成功后你可以在Bintray主页左下角的My Recent Packages栏目中看到新的package。

my_recent_packages

点进去后会有这样一个提示,让你在七天之内公开,点击Publish。

publish_repo

JCenter

然后为了让所有开发者都可以使用,你需要将类库添加到JCenter。操作很简单,只需要点击如下所示的按钮,而后你需要填写有关类库的信息。

add_to_jcenter

我提交之后过几个小时就有邮件通知添加成功,大家耐心等待。添加成功后会变成如下景象。

link_to_jcenter

在每次发新版时,点击Publish后不会立即生效,也就是说如果在Gradle中想要立即引用新版,会无法解析,因为有几分钟的延迟,等到左下角的Maven build Settings中的依赖代码改变,或是右上侧Version栏目下新版信息有了tweeter标识后就可以正常引用了。

maven_build_settings

version_info

托管到GitHub,写readme,推广与维护

恭喜你,你已经完成了所有有坑的环节,现在离完成只剩一个GitHub了!GitHub对于你的开源库而言有如下几个作用,一是可以维护一份文档,也就是README,告知大家相关信息;二是可以将代码以很方便的形式让大家参考并做二次开发;第三点在于GitHub是世界上最大的同性交友平台,是所有开源库的集散地;第四点在于大家可以很方便的提交Issue给你报Bug。

README

有很多文章讲了如何将项目托管到GitHub,这里不再重述。首先我们说说README这个文件。在GitHub的每个项目中,根目录中的README.md会被用于展示,大家可以在这个文档中展示库的相关信息,至少要包含依赖语句。除此以外,我建议大家在README中添加以下几项信息:

  • 效果展示:如果你做的是View,那么给出一个截图或是Gif,如果是其他组件,最好也给出可视化很强的图片,因为图片对人的冲击力远大于文字。如果你要做动图,并进行图片录制的话,首先推荐一个录屏工具Telecine,Jake Wharton出品,无需root,方便传输,这是我对比多个市场上下载量最大的录屏工具后作出的推荐。然后,在你将视频转成gif后,可以使用Photoshop对Gif进行裁剪与剪辑,只需打开时间轴窗口即可,很方便。建议你将gif图片放在项目目录中,而不是在README中以外链形式添加,不然可能显示异常。

  • 样例下载:开发者如果被你的展示图所吸引,会希望能下载一个样例。建议大家能同时给出apk的下载链接和二维码。由于国内很多人通过微信扫二维码,而微信浏览器又不支持下载,大家需要给服务器上的apk文件设置请求头,将Content-Type设置为application/octet-stream,强制微信跳转到外部浏览器。

  • 功能与使用范例:给出支持的功能与相对应的最基本的使用方式,最好做出相关说明,比如参数等等。

  • License:把刚才选择的License添加到README中。

大家不妨多参考Star数很高的开源项目的README。

推广

你已经成功地发布了开源库,为了让更多的人看到你的开源库,这里给出几个推广方式:

  • 微博:微博可以说是推广库的最佳方式,正确的使用姿势是:一句话说清楚库的功能,给个地址,放个图,艾特几个大V,剩下的就看你的库的质量了。

  • 周报:可以将你的库投稿给各种周报,每期周报里都会推送各种库,在这里推荐两个周报:Android开发技术周报国外Android周报。各种各样的周报是很多的,大家多多发掘。

  • 推广这种事是需要发挥想象力的。比如我在这里写个博客顺便就打个广告。

维护

当有人在使用你的开源库并发现问题时,会向你提Issue。还有可能会有人想参与进来,和你一同开发。

但是,所有开源库都会经历从积极维护到停止维护(Deprecated)的过程,这也推进着开源事业不断地向前发展。所有代码与开源库都有过时的一天,只剩下几颗星星留在你的主页上,像一枚勋章,映射着你昔日的张狂。

祝大家在开源之路走的开心。有任何问题,都可以给我发邮件,在我的博客或公众号留言,或是参考我的GitHub库DecentBanner

欢迎关注我的公众号,将零碎时间都用在刷干货上!

qr