api與implementation的區別

1、從3.4版本的gradle開始,compile已經被api與implementation取代,官網也給出了三者之間的區別:android

 

圖一、api與implementation的區別api

 

從官網介紹能夠看出,implementation可讓module在編譯時隱藏本身使用的依賴,可是在運行時這個依賴對全部模塊是可見的。而api與compile同樣,沒法隱藏本身使用的依賴。
具體經過例子來看,下圖爲項目結構:app

 

項目結構圖maven


app依賴模塊mylibrary一、mylibrary1依賴模塊mylibrary3
mylibrary1以下:ide

package com.example.mylibrary1;
/**
 * @author heshufan
 * @date 2018/8/9.
 */
public class MyClass1 {
    public static String  get(){
        return "MyClass1";
    }
}

mylibrary3以下:模塊化

package com.example.mylibrary3;
/**
 * @author heshufan
 * @date 2018/8/13.
 */
public class MyClass3 {
    public static String get(){
        return "MyClass33";
    }
}

當mylibrary1 使用api依賴mylibrary3時,gradle

api project(':mylibrary3')

在App中能夠直接調用MyClass3類,也就是依賴能夠傳遞。ui

package com.example.heshufan.learnapiandimp;
import com.example.mylibrary1.MyClass1;
import com.example.mylibrary3.MyClass3;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyClass1.get0();
        MyClass3.get();
    }
}

當mylibrary1使用implemention依賴mylibrary3時,設計

implementation project(':mylibrary3')

在App中,沒法直接調用mylibrary3code

 

沒法直接調用MyClass3

 

從上面的例子能夠看出,在多module中,implementation確實能夠起到隱藏依賴的做用,網上不少的文章都只講到了這點,那麼這樣作的目的是什麼呢?其實這並非Google設計implemention與api的目的,由於官方文檔中說這樣設計的目的在於減小build的時間,那麼implemention是如何減小build time的呢?

2、咱們再新建一個module:mylibrary4,如今的項目結構如圖:

 

項目結構圖

 

那麼如今的項目層級以下圖所示:

 

項目依賴層級圖


一、若是mylibrary3使用api依賴mylibrary4,那麼當mylibrary4發生變化時,編譯須要從新編譯mylibrary四、mylibrary三、mylibrary1;
二、若是mylibrary3使用implemention依賴mylibrary4,那麼當mylibrary4發生變化時,編譯須要從新編譯mylibrary四、mylibrary3,這個時候不須要編譯mylibrary1,這樣就能夠節約build time;

爲此我驗證了兩種依賴下項目的build time,每次從新編譯前clean project,改變mylibrary4,而後rebuild project,再查看build time。

使用implemention的build time:

 

implementation

 

使用api的build time

 

1api.jpg


能夠看到api的build time比implemention多了1秒多,屢次運行都多了1秒多,這仍是在module比較小的狀況下。若是包比較多,比較大,那麼能夠節約的時間是很是可觀的。
總結起來:若是api依賴,一個module發生變化,這條依賴鏈上全部的module都須要從新編譯;而implemention,只有直接依賴這個module須要從新編譯。

3、如今在回過頭來看一下依賴傳遞的問題,以前驗證了使用implemention,app不能拿到MyClass3,這是在本地依賴的狀況下,而如今的模塊化開發多采用遠程依賴的模式進行合做。那麼若是採用maven遠程依賴呢?
一樣採用以前的例子,咱們新建一個module :mylibrary2

 

mylibrary2

 

咱們將其上傳到咱們的本地maven

 

maven倉庫


最後在mylibrary1中利用implemention依賴mylibrary2

//mylibrary1
    implementation 'com.example:mylib:1.0.3'

而後咱們再將mylibrary1上傳到本地maven,而後在app中遠程依賴mylibrary1

//mylibrary2
    implementation 'com.example:myClass2:1.0.0'

也就是app遠程implementation mylibrary1,mylibrary1遠程implemention mylibrary2,這時候app就能夠直接拉到mylibrary2中的myClass2類(命名不規範,別學我)

 

沒有報錯

而若是app本地implementation mylibrary1,mylibrary1遠程implemention mylibrary2,這時候app則不能獲取到mylibrary2中的myClass2類,依然起到了依賴隔離的做用。

由以上能夠看到在所有遠程依賴模式下,不管是api仍是implemention都起不到依賴隔離的做用。不過,在遠程依賴模式下,依賴的一個模塊若是版本發生變化,implemention與api的構建速度誰快誰慢還須要進一步研究。

綜上,在多層次模塊化(大於等於三層module)開發時,若是都是本地依賴,implementation相比api,主要優點在於減小build time。若是隻有兩層module,api與implemention在build time上並沒有太大的差異。

參考資料:
一、https://jeroenmols.com/blog/2017/06/14/androidstudio3/
二、https://www.jianshu.com/p/dd932f951137

做者:一杉先生 連接:https://www.jianshu.com/p/8962d6ba936e 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

相關文章
相關標籤/搜索