1 需求
你是否用過友盟、微信鳖眼、微博、支付寶的sdk嚼摩?
有沒有想研究一下對(duì)方的代碼钦讳,卻發(fā)現(xiàn)已經(jīng)混淆了?
你有沒有想過有一天枕面,你也會(huì)進(jìn)入一家牛逼的企業(yè)愿卒,需要發(fā)布自己SDK?
又或者僅僅是滿足自己的虛榮心潮秘,發(fā)布一個(gè)自己得意的工具琼开?
這篇文章正是為實(shí)現(xiàn)這一目的
2 開發(fā)環(huán)境及工具
- MAC(Windows也無所謂,路徑不同而已)
- Android Studio 2.3.1
- JDK 1.8
- Github
- Maven
3 實(shí)現(xiàn)步驟
3.1 新建工程
新建一個(gè)工程TestModule枕荞,選擇empty activity柜候,讓Android studio生成一個(gè)最簡(jiǎn)單的activity,這個(gè)工程我們用來做什么的呢躏精?
大家知道渣刷,你交付的代碼是需要有質(zhì)量保證的,因此需要對(duì)他有過詳盡的測(cè)試矗烛,這個(gè)工程就是我們的測(cè)試工程辅柴,簡(jiǎn)單來說就模擬用戶的開發(fā)環(huán)境
3.2 新建module
新版本的Android Studio已經(jīng)支持模塊開發(fā),我們選擇File-->New-->New Module瞭吃,此時(shí)會(huì)有一個(gè)彈框碌嘀,我們選擇Android Library,并起名為MySDK
新建成功后虱而,你會(huì)發(fā)現(xiàn)左側(cè)工程導(dǎo)航欄里筏餐,多出了一個(gè)模塊工程,這個(gè)工程有著獨(dú)立的一套目錄結(jié)構(gòu)牡拇,跟app一樣魁瞪。他有自己獨(dú)立的gradle配置
3.2 建立功能類
在mysdk這個(gè)模塊下的操作跟普通的Android工程沒有任何區(qū)別穆律,所以我們按平常一樣,建立一個(gè)新的activity导俘,起名叫mySDKTest峦耘,并自動(dòng)建好layout。這篇文章的重點(diǎn)不在功能旅薄,所以我們?cè)谶@個(gè)layout中隨便建一個(gè)什么view辅髓,我們就建一個(gè)button吧,實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的功能少梁,點(diǎn)擊這個(gè)button洛口,就打印出一句“You clicked module button”。
假設(shè)凯沪,這個(gè)就是我們最終要封裝的功能第焰。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button"
android:text="Button"/>
</LinearLayout>
public class mySDKTest extends AppCompatActivity {
private static final String TAG = "mySDKTest";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_sdktest);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i(TAG, "You clicked module button!!");
}
});
}
}
3.3測(cè)試功能
此時(shí),你會(huì)發(fā)現(xiàn)你根本run不起來這個(gè)工程妨马,根本沒有選項(xiàng)去跑這個(gè)功能挺举,可選的只有app,沒有mysdk烘跺。
這就是我們?cè)?.1新建工程時(shí)說這個(gè)工程是測(cè)試工程的原因湘纵,因?yàn)镸odule根本跑不起來的啊
3.4配置依賴
因此我們要用到app來測(cè)試SDK,所以我們要在app中配置依賴mysdk滤淳。
方法是在app的build.gradle里加入依賴語句
compile project(':mysdk')
此時(shí)梧喷,再去app的MainActivity里,你就可以import我們剛剛建立的mySDKTest了娇钱。
同樣伤柄,我們實(shí)現(xiàn)一個(gè)button,點(diǎn)擊跳轉(zhuǎn)到mysdk的activity文搂。
Button button = (Button)findViewById(com.flame.mysdk.R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, mySDKTest.class);
startActivity(intent);
}
});
這樣就能跑起來測(cè)試了
跑起來后适刀,點(diǎn)擊跳轉(zhuǎn)按鈕,會(huì)發(fā)現(xiàn)進(jìn)入了sdk的頁面煤蹭,再點(diǎn)擊按鈕笔喉,會(huì)打出那句log。
之后你可以根據(jù)自己的需求硝皂,繼續(xù)開發(fā)常挚,并測(cè)試。
3.5 管理依賴
3.5.1簡(jiǎn)單方式
我們假設(shè)奄毡,你已經(jīng)完成了功能開發(fā)和測(cè)試,現(xiàn)在需要發(fā)布出去或者提交給用戶贝或,如何給到用戶呢吼过?
我們打開mysdk的目錄锐秦,在build-->outputs-->aar下面是有生成的AAR文件,你把這個(gè)文件拷貝一份給用戶其實(shí)盗忱,也是可以的酱床,大家搜一下導(dǎo)入AAR文件即可。
3.5.2 Maven + Github
Apache Maven是Apache開發(fā)的一個(gè)工具趟佃,提供了用于貢獻(xiàn)library的文件服務(wù)器扇谣。
通過Maven + Github的方式,我們可以更簡(jiǎn)單的發(fā)布闲昭,更便捷的做版本管理罐寨;用戶可以更簡(jiǎn)單的導(dǎo)入。
也是我們重點(diǎn)要講的內(nèi)容
3.5.2.1配置打包gradle
在mysdk的目錄下汤纸,新建一個(gè)名為maven-release-aar.gradle的文件衩茸,并在build.gradle中添加如下字段:
apply from: 'maven-release-kline-aar.gradle'
3.5.2.2配置maven-release-aar.gradle
可以這么理解,maven-release-aar.gradle就是我們用來設(shè)置打包的腳本贮泞,在文件中添加如下代碼:
注意看注釋!幔烛!
// 1.maven-插件
apply plugin: 'maven'
// 2.maven-信息
ext {// ext is a gradle closure allowing the declaration of global properties
PUBLISH_GROUP_ID = 'com.flame'
PUBLISH_ARTIFACT_ID = 'mySDK'
PUBLISH_VERSION = android.defaultConfig.versionName
}
// 3.maven-輸出路徑
uploadArchives {
repositories.mavenDeployer {
//這里就是最后輸出地址啃擦,在自己電腦上新建個(gè)文件夾,把文件夾路徑粘貼在此
//注意”file://“ + 路徑饿悬,有三個(gè)斜杠令蛉,別漏了
repository(url: "file:///Users/flame/Documents/sourceTree/mysdk")
pom.project {
groupId project.PUBLISH_GROUP_ID
artifactId project.PUBLISH_ARTIFACT_ID
version project.PUBLISH_VERSION
}
}
}
//以下代碼會(huì)生成jar包源文件,如果是不開源碼狡恬,請(qǐng)不要輸入這段
//aar包內(nèi)包含注釋
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.sourceFiles
}
artifacts {
archives androidSourcesJar
}
3.5.2.3生成AAR文件
- 接下來就是生成最終的AAR文件了珠叔,在Android studio右側(cè)有個(gè)gradle側(cè)邊欄,點(diǎn)擊會(huì)有如下畫面弟劲,選擇mysdk祷安,點(diǎn)擊uploadArchives
- 最后build成功
- 再去上面配置好的maven輸出路徑下看,會(huì)發(fā)現(xiàn)已經(jīng)有生成文件了兔乞。
- 注意看汇鞭,version是1.0,而且有jar包庸追,解壓jar包就會(huì)得到全部源文件
- 如果在上一步不開源霍骄,注釋掉生成jar包的代碼,這里就不會(huì)有jar包
3.5.2.4上傳至github
- 將整個(gè)文件夾上傳至Github淡溯,注意读整,要上傳的是完整的路徑
- 在github中新建organization,create new-new organization.
- 此處需要注意咱娶,create new有兩個(gè)選項(xiàng)米间,new repository和new organization煎楣,此處務(wù)必要選擇organization,雖然區(qū)別不大车伞,但是假如選擇repository的話不能夠作為私有倉庫導(dǎo)入到新項(xiàng)目(報(bào)Failed to resolve錯(cuò)誤)
3.5.2.5 管理版本
剛剛提到之所以用maven的一個(gè)原因就是版本控制择懂,這里我們就演示一下,所謂的版本控制
- 打開mysdk的build.gradle另玖,修改defaultConfig下的versionName 為"1.1"
再來一次#3.5.2.3 - uploadArchives困曙,build成功后再看目錄,已經(jīng)生成了新的版本1.1
再上傳至Github
這樣我們就有了清晰的版本控制
3.6 如何引用
在之前的章節(jié)中谦去,我們已經(jīng)生成了對(duì)應(yīng)代碼慷丽,那么如何引用呢?
首先我們先要在app的build.gradle里面移除之前的依賴方法
//注釋掉這段鳄哭,不需要了
//compile project(':mysdk')
3.6.1 本地模式
代碼就在我們本地要糊,我們當(dāng)然可以就近引用咯
我們?cè)赼pp的build.gradle中加入如下代碼,這里已經(jīng)省略了無關(guān)代碼
repositories {
jcenter()
//略
//指定絕對(duì)路徑
maven { url "file:///Users/flame/Documents/sourceTree/mysdk" }
}
dependencies {
//略
//mysdk妆丘,這里可以指定版本锄俄,我們有1.0,1.1兩個(gè)版本可選
compile('com.flame:mySDK:1.1')
}
3.6.2 網(wǎng)絡(luò)模式
上面提到的方法,當(dāng)然是少數(shù)勺拣,畢竟我們大多數(shù)都是在網(wǎng)絡(luò)導(dǎo)入依賴庫奶赠,這里就是需要用到之前上傳至Github的代碼了。
只需把路徑指向Github即可
repositories {
jcenter()
//略
//指定Github路徑
maven { url "https://github.com/flameandroid/mysdk/raw/master" }
}
dependencies {
//略
?
//mysdk药有,這里可以指定版本毅戈,我們有1.0,1.1兩個(gè)版本可選
compile('com.flame:mySDK:1.1')
}
3.7 混淆
我們打開External Libraries,會(huì)發(fā)現(xiàn)mySDK已經(jīng)導(dǎo)入工程愤惰,而且還是完全開源的苇经。
而很多時(shí)候我們是不需要開源的,那么如何做到呢宦言?其實(shí)和普通的Android打包混淆一模一樣
把混淆過的代碼上傳至Github扇单,這樣我們就完成了SDK的制作和發(fā)布
release {
// 不顯示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//混淆
minifyEnabled true
//Zipalign優(yōu)化
zipAlignEnabled true
// 移除無用的resource文件
shrinkResources true
//前一部分代表系統(tǒng)默認(rèn)的android程序的混淆文件,該文件已經(jīng)包含了基本的混淆聲明蜡励,后一個(gè)文件是自己的定義混淆文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
4 注意事項(xiàng)
- 注意路徑一定要寫對(duì)令花,特別是大小寫,路徑的大小寫不對(duì)是找不到文件的凉倚,這雖然是低級(jí)錯(cuò)誤兼都,但其實(shí)挺常見的
- 注意Github路徑不是常見的https://github.com/flameandroid/mysdk.git,
而是https://github.com/flameandroid/mysdk/raw/master - 注意如果選擇了混淆稽寒,切勿在打包那步生成了jar扮碧,還上傳到Github了,否則白混淆了