Android Library打造自己的SDK,并Maven發(fā)布

1 需求

你是否用過(guò)友盟、微信、微博、支付寶的sdk?
有沒(méi)有想研究一下對(duì)方的代碼,卻發(fā)現(xiàn)已經(jīng)混淆了?
你有沒(méi)有想過(guò)有一天,你也會(huì)進(jìn)入一家牛逼的企業(yè),需要發(fā)布自己SDK?
又或者僅僅是滿足自己的虛榮心,發(fā)布一個(gè)自己得意的工具?

這篇文章正是為實(shí)現(xiàn)這一目的

2 開(kāi)發(fā)環(huán)境及工具

  • MAC(Windows也無(wú)所謂,路徑不同而已)
  • 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è)工程我們用來(lái)做什么的呢?
大家知道,你交付的代碼是需要有質(zhì)量保證的,因此需要對(duì)他有過(guò)詳盡的測(cè)試,這個(gè)工程就是我們的測(cè)試工程,簡(jiǎn)單來(lái)說(shuō)就模擬用戶的開(kāi)發(fā)環(huán)境

3.2 新建module

新版本的Android Studio已經(jīng)支持模塊開(kāi)發(fā),我們選擇File-->New-->New Module,此時(shí)會(huì)有一個(gè)彈框,我們選擇Android Library,并起名為MySDK

新建Android Module

新建成功后,你會(huì)發(fā)現(xiàn)左側(cè)工程導(dǎo)航欄里,多出了一個(gè)模塊工程,這個(gè)工程有著獨(dú)立的一套目錄結(jié)構(gòu),跟app一樣。他有自己獨(dú)立的gradle配置

相同目錄結(jié)構(gòu)

3.2 建立功能類

在mysdk這個(gè)模塊下的操作跟普通的Android工程沒(méi)有任何區(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è)就是我們最終要封裝的功能。

Paste_Image.png
<?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不起來(lái)這個(gè)工程,根本沒(méi)有選項(xiàng)去跑這個(gè)功能,可選的只有app,沒(méi)有mysdk。

只有app可選.png

這就是我們?cè)?.1新建工程時(shí)說(shuō)這個(gè)工程是測(cè)試工程的原因,因?yàn)镸odule根本跑不起來(lái)的啊

3.4配置依賴

因此我們要用到app來(lái)測(cè)試SDK,所以我們要在app中配置依賴mysdk。
方法是在app的build.gradle里加入依賴語(yǔ)句

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);
            }
        });

這樣就能跑起來(lái)測(cè)試了
跑起來(lái)后,點(diǎn)擊跳轉(zhuǎn)按鈕,會(huì)發(fā)現(xiàn)進(jìn)入了sdk的頁(yè)面,再點(diǎn)擊按鈕,會(huì)打出那句log。
之后你可以根據(jù)自己的需求,繼續(xù)開(kāi)發(fā),并測(cè)試。

進(jìn)入sdk頁(yè)面,并打印log

3.5 管理依賴

3.5.1簡(jiǎn)單方式

我們假設(shè),你已經(jīng)完成了功能開(kāi)發(fā)和測(cè)試,現(xiàn)在需要發(fā)布出去或者提交給用戶,如何給到用戶呢?
我們打開(kāi)mysdk的目錄,在build-->outputs-->aar下面是有生成的AAR文件,你把這個(gè)文件拷貝一份給用戶其實(shí),也是可以的,大家搜一下導(dǎo)入AAR文件即可。

生成文件

3.5.2 Maven + Github

Apache Maven是Apache開(kāi)發(fā)的一個(gè)工具,提供了用于貢獻(xiàn)library的文件服務(wù)器。
通過(guò)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'
Paste_Image.png

3.5.2.2配置maven-release-aar.gradle

可以這么理解,maven-release-aar.gradle就是我們用來(lái)設(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包源文件,如果是不開(kāi)源碼,請(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文件

  • 接下來(lái)就是生成最終的AAR文件了,在Android studio右側(cè)有個(gè)gradle側(cè)邊欄,點(diǎn)擊會(huì)有如下畫(huà)面,選擇mysdk,點(diǎn)擊uploadArchives
uploadArchives
  • 最后build成功
build success
  • 再去上面配置好的maven輸出路徑下看,會(huì)發(fā)現(xiàn)已經(jīng)有生成文件了。
  • 注意看,version是1.0,而且有jar包,解壓jar包就會(huì)得到全部源文件
  • 如果在上一步不開(kāi)源,注釋掉生成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的話不能夠作為私有倉(cāng)庫(kù)導(dǎo)入到新項(xiàng)目(報(bào)Failed to resolve錯(cuò)誤)

3.5.2.5 管理版本

剛剛提到之所以用maven的一個(gè)原因就是版本控制,這里我們就演示一下,所謂的版本控制

  • 打開(kāi)mysdk的build.gradle,修改defaultConfig下的versionName 為"1.1"
修改版本
  • 再來(lái)一次#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)省略了無(wú)關(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)入依賴庫(kù),這里就是需要用到之前上傳至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 混淆

我們打開(kāi)External Libraries,會(huì)發(fā)現(xiàn)mySDK已經(jīng)導(dǎo)入工程,而且還是完全開(kāi)源的。

而很多時(shí)候我們是不需要開(kāi)源的,那么如何做到呢?其實(shí)和普通的Android打包混淆一模一樣

把混淆過(guò)的代碼上傳至Github,這樣我們就完成了SDK的制作和發(fā)布

        release {
            // 不顯示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"
            //混淆
            minifyEnabled true
            //Zipalign優(yōu)化
            zipAlignEnabled true

            // 移除無(wú)用的resource文件
            shrinkResources true
            //前一部分代表系統(tǒng)默認(rèn)的android程序的混淆文件,該文件已經(jīng)包含了基本的混淆聲明,后一個(gè)文件是自己的定義混淆文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

4 注意事項(xiàng)

  • 注意路徑一定要寫(xiě)對(duì),特別是大小寫(xiě),路徑的大小寫(xiě)不對(duì)是找不到文件的,這雖然是低級(jí)錯(cuò)誤,但其實(shí)挺常見(jiàn)的
  • 注意Github路徑不是常見(jiàn)的https://github.com/flameandroid/mysdk.git
    而是https://github.com/flameandroid/mysdk/raw/master
  • 注意如果選擇了混淆,切勿在打包那步生成了jar,還上傳到Github了,否則白混淆了
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容