成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么要開發Android庫?

移動開發 Android
這次分享由我們的 Emanuele Zattin 分享一些他在開發 Java 和 C/C++ 庫上的一些最佳實踐。探討下 API 設計,CI 技術,以及對于性能的看法,你會了解到對你工作很有幫助的一些工具。

不論是你要執行一個特定的任務,模塊化你的代碼,或者只是為了更優雅地重用你的代碼,有些時候,作為開發者,通常會考慮開發庫來實現。但開發庫是個挺困難的事情。由 Bay Android Dev Group 主辦,這次分享由我們的 Emanuele Zattin 分享一些他在開發 Java 和 C/C++ 庫上的一些***實踐。探討下 API 設計,CI 技術,以及對于性能的看法,你會了解到對你工作很有幫助的一些工具。

為什么要開發Android庫?

為什么要開發 Android 庫?

為了追求更簡潔的代碼和更好的代碼管理,我們通常需要把代碼拆分成不同的邏輯單元,所以,開發 Android 庫的***個原因就是為了模塊化。這也引申出我們開發庫的第二個原因:代碼重用。一旦你的代碼模塊化后,你可以將它用在很多不同的地方。相比高耦合度的代碼,基于庫的代碼管理讓你更容易的替換其中的代碼,以適應不同的場景。還有一個原因,其實就是 “虛榮”,如果你有一個很不錯的想法或者提出一種新的解決特定問題的方案,寫個庫會是一個將這個想法分享給全世界,并且讓大家都能用到的一個好辦法。

為什么是開發 Android 庫而不是 Java 庫呢?如果你的庫要和 Android 的 UI,消息系統,設備傳感器,或者原生代碼打交道,那么你只能開發 Android 庫,而不是 Java 庫。

我們開始前,首先,打開你的 Android Studio,并且新建一個項目!Android Studio 并不支持直接新建一個新的庫,這里有幾種解決辦法,如下:

方法一 - Hack 方案:

  • 創建 Application Project
  • 添加 Library Project
  • 刪除 Application Module

簡單粗暴效果好

方法二 - 使用命令行,Android 自帶了很多很多的工具,創建 Android 庫也是其中的一個命令。傳入一個 ID 參數允許你指定特定的編譯 版本,也可以通過傳參指定項目包名,以及你想要運行的 Gradle 的版本。 Gradle 是一個極其有用和靈活的自動化構建工具,你可以非常容易地運行各種插件,來加速你的開發,比 Maven 和 Ant 不知道高到哪里去了。

第二步: 代碼,代碼,代碼!

在開發庫的時候,API 設計非常重要, Joshua Bloch 是這方面的專家,他的 Effective Java 盡管是基于 Java 1.5, 但仍然有很多有價值的技巧。他曾經做過一個 名叫 如何設計優秀的 API,為何如此重要 的精彩的演講,因此我想分享一些他在 API 設計上的一些觀點。

那么,一個好的 API 應該具備哪些特點?

簡單易學,你并不想讓開發者不斷地去查看文檔,因此你在設計時候的命名法、類名和參數名一定要盡可能的不言自明。

  • API 要少出錯,所以要把 API 設計得堅如磐石。
  • API 一定要易讀,易維護,畢竟你在很長一段時間內要和這些代碼打交道,特別是它一旦流行開以后,你會收到很多的新功能的請求和漏洞報告。
  • API 的可擴展性也至關重要。想想 Jenkins :雖然不是一個 API,但是他是一個非常成功的開源項目,一部分原因是因為他易于擴展,以及為他開發插件。
  • ***,你一定要明確你的受眾,不論受眾是你自己、你的團隊、你工作所在的公司或是整個世界,你的 API 都要做到對你的受眾友好。

測試很重要,對庫而言更加重要,因為你無法預知你的受眾將如何去使用它們。很幸運的是,在 Android 上測試庫跟測試 App 差異并不大。你可以使用 Android TestCase ,也可以用一些其他的 Android 測試工具框架來做測試。

Android 的測試組件一個不好的地方就是大家通常會卡到 JUnit 3 上,尤其是你發現你不能用類似 Robolectric 這樣不支持 Native 代碼的工具。JUnit3 不支持一個對庫開發很重要的測試特性:參數化測試。如果你想用一些列測試參數來測試的方法,你可以試試用 Square 開發的一個叫: Burst 的庫。它很好地解決了這個問題。

自動化你的測試! Jenkins 是一個非常贊的工具來解決實現自動化測試。他提供了超過 1000 個插件,其中一些專為 Android 開發設計。我強烈推薦以下插件:

  • Job Config History 插件, 它可以在出狀況的時候通過配置文件重新恢復現場。
  • Git 插件,以及與他類似的一些插件,比如: GitHub , GitHub pull request , GitLab , 等等。
  • 讓執行任務和自動化變得簡單的 Gradle 插件。Gradle 非常擅長自動化,你可以在 Jenkins 的 Gradle 里運行很多你自己的操作邏輯。
  • Android Emulator 插件,這個不僅僅是個模擬器。 當你想要測試不同屏幕分辨率以及內存使用的時候,這個插件非常有用。

另一個測試方案是寫測試用的 App。這種方案在很多時候都很有用:它可以幫你驗證你的測試用例,間接地測試,而且可以確保你的 App 不會崩潰或者無響應。想要做測試 App,推薦用 Gradle 的 這個插件 ,它同時支持發送指令給不同的 Android 設備。

在你準備要發布你的庫的時候,你會作何選擇?目前有兩個選擇:發布 Jar, 或者發布 Aar(Android 歸檔文件),如果你還不知道 Aar,我來做個簡單介紹,Aar 是 Google 為了能讓庫文件包含 UI 元素而提出的一種文件格式,他可以讓你不僅僅包含 Java 類,還可以存儲數據和資源在里面。他在 Android 和 Android Studio 上非常有用,Ant 和 Eclipse 并不支持這種格式。

一個不好的事情是盡管使用本地的 Aar 是可行的,有兩種方案來實現這個,但他們都很麻煩。尤其是你想用你剛剛生成的 Aar 來做 App 測試。所以,如何選擇發布哪種格式,***就歸結為,你是否必須要支持 Eclipse,如果是,那么沒得選,只能用 Jar。

問題產生的原因就是因為 Android Gradle 插件產生的是 Aar,而不是 Jar 文件,盡管如此,事實上 Jar 文件舊包含在 Aar 文件里,其實你只要復制出來 Jar 文件,然后重命名他就好了。下面的代碼就是一個簡單的 Gradle Demo 來做這件事情: 拷貝文件(通常會被命名為:’classes.jar’),然后重命名成你想要的名字。

 

  1. task generateJar(type: Copy) { 
  2.     group 'Build' 
  3.     description 'blah blah...' 
  4.     dependsOn assemble 
  5.     from 'build/intermediates/bundles/release/classes.jar' 
  6.     into 'build/libs' 
  7.     rename('classes.jar''awesome-library.jar'

 

下一個問題是:我們應該發布在哪?如果你計劃開源它,那么想都不用想,就用酷炫的 Bintray 。Bintray 盡管需要你準備更多的東西,但依舊用起來非常簡單。僅僅需要一個源碼 Jar 文件,以及一個 Javadoc 的 Jar 文件,這兩個都非常容易生成。這樣一來,你基本上只要指定代碼路徑,就可以遍歷所有的 Variant。

 

  1. // sources Jar 
  2. task androidSourcesJar(type: Jar) { 
  3.     from android.sourceSets.main.java.srcDirs  
  4.  
  5. // Javadoc Jar 
  6. android.libraryVariants.all { variant -> 
  7.     task("javadoc${variant.name.capitalize()}", type: Javadoc) { 
  8.         description "Generates Javadoc for $variant.name." 
  9.         group 'Docs' 
  10.         source = variant.javaCompile.source 
  11.         ext.androidJar = files(plugins 
  12.                                 .findPlugin("com.android.library"
  13.                                 .getBootClasspath()) 
  14.         classpath = files(variant.javaCompile.classpath.files) + 
  15.                     ext.androidJar 
  16.         exclude '**/BuildConfig.java' 
  17.         exclude '**/R.java' 
  18.     } 

Bintray 也為生產發布提供了一個很精美卻不是那么好用的 Gradle 插件 ,尤其是你只是一個 Gradle 新手的話…… 另外,帶 Web 界面的發布工具也很是有用。你只要上傳這三個文件,再填一些信息,就可以了。一開始,你可以使用那些 web 方案,當你對 Gradle 插件的使用和自動化非常熟悉的時候,就讓 Jenkins 去幫你做這些發布工作吧。

Advanced Topics

注解處理技術( Annotation processing technologies )現在已經非常流行了。在編譯的時候,Javac 通常會找到你定義的注解并且在他們之上做操作,因此你能做的通常就是生成新的類和 Java 文件。你可以寫你自己的注解處理器。雖然很不簡單,但是可行。

注解技術非常擅長處理兩件事情。一是減少重復代碼(boilerplate),另一件拿手的就是優化運行時的反射(introspection)。在運行時執行反射操作是非常慢的,因此你***能在編譯時期就去優化你的程序,推薦一些比較流行的用注解來處理數據的庫: Dagger , Butter Knife , AutoValue / Autoparcel , 以及 Realm 。

一個不好的消息是:Android API 不能給注解提供正確的包路徑。解決這個問題的方法是創建兩個子項目,一個用來指向注解,另一個指向注解處理器。注解同時需要注解處理器和你的代碼。因此,你的 Android 庫項目,將會有兩個子項目。創建完兩個子項目后,你需要將他們都打包在一起,最終打包出來的東西不僅僅是你的 jar 文件,同時還有注解和注解處理器。你還需要修改 javadoc 任務,把注解部分的文檔也添加進去,以便讓開發者能夠讀到所有的文檔。

 

  1. // Jar 
  2. task androidJar(type: Jar) { 
  3.     dependsOn assemble 
  4.     group 'Build' 
  5.     description 'blah blah' 
  6.     from zipTree( 
  7.         'build/intermediates/bundles/release/classes.jar'
  8.     from zipTree( 
  9.         '../annotations-processor/build/libs/processor.jar'
  10.     from zipTree( 
  11.         '../annotations/build/libs/annotations.jar')  
  12.  
  13. // javadoc tasks 
  14. android.libraryVariants.all { variant -> 
  15.     task("javadoc${variant.name.capitalize()}", type: Javadoc) { 
  16.         description "Generates Javadoc for $variant.name." 
  17.         group 'Docs' 
  18.         source = variant.javaCompile.source 
  19.         source "../annotations/src/main/java" 
  20.         ext.androidJar = files(plugins 
  21.                                 .findPlugin("com.android.library"
  22.                                 .getBootClasspath()) 
  23.         classpath = files(variant.javaCompile.classpath.files) 
  24.                     + ext.androidJar 
  25.         exclude '**/BuildConfig.java' 
  26.         exclude '**/R.java' 
  27.     }  

Native Code 基本上都是和 NDK 打交道,整個工作流掌握起來很多很麻煩。如果你了解 C/C++,那***不過,不然你要花大量的時間去學習新東西。Gradle 和 Android Studio 對 NDK 的支持并不好,當你嘗試著去使用 NDK 模塊的時候,他會警告你說:當前 NDK 已經不被支持了。Google 現在在盡可能的去讓 Gradle 支持去支持 Native 插件。在此之前,我們還是必須得手動的搭建整個工具鏈,手動的編譯以及把編譯出來的文件拷貝到正確的位置。

遇到 NDK 不被支持的警告要做呢?一個方法是忽略警告,因為它依然可以工作。得留意的是,現在沒有對 ldFlags 的定義,因此你不能為鏈接器指定 flag 參數。如果你需要這些參數,另一個方法是使用 Native 插件。這個方法可能很快就被廢棄了,他需要你自己處理單獨的工具鏈的搭建以及將生成文件從一個項目轉移到對應的項目下。

如果你使用 jar 文件,如何才能包含基于 Native 實現的庫呢?其實只用在 Building 的時候動動手腳就好了。如下所示,修改你的 “jar” 任務就可以了。

 

  1. task androidJar(type: Jar, dependsOn: ['assemble']) { 
  2.     group 'Build' 
  3.     description 'blah blah' 
  4.     from zipTree('build/intermediates/bundles/release/classes.jar'
  5.     from(file('src/main/jniLibs')) { 
  6.         into 'lib' 
  7.     } 
  • 擁抱 Gradle:可能需要花時間學習,但是非常值。
  • 探索 Gradle 插件!有數不清的插件,總有一款適合你。
  • 自動化你的測試。盡可能的用 Jenkins和自動化工具。
  • 如果你要開源你的炫酷組件,Bintray 是個好選擇。

Q: Jenkins 上用 Gradle 的優勢有哪些? Emanuele:優勢就是 Gradle 有一些設置選項,包括你在你電腦上運行的 Gralde 或者 Gradle Wrapper 版本,插件能在出問題的時候讓你通過 log 更容易的定位到問題所在。

Q: 你提到注解很有用,因為他們是在編譯的時候處理問題,那么運行時的注解有沒有什么特殊之處? Emanuele: 如果你想的話,你也可以在運行時調用注解,執行反射操作。但是相比于在編譯時期處理慢很多。在 Android 上就更慢了,所以你用著用著就不想這么搞了。

Q: 你之前介紹了這么多有用的庫,他們都會對 Android 性能產生很大影響么? Emanuele:不,我只是說你可以在編譯時做反射優化。有的時候,只有運行時反射才能拿到一些你程序執行時候需要的信息,所以那種情況你也只能那樣做了。

Q: 在處理注解的時候, Javapoet 是個不錯的庫,但依然要讀取注解并且在類繼承關系中尋找,你有沒有處理這個的好的方案? Emanuele: 很不幸,沒有。事實上,javapoet 只能在你生成新的類的時候幫到你。如果沒有那么多的代碼量,你也可以不用任何的庫,只用模板。問題通常出在對象反射的限制上。你可以拿到注解的類,等等,但是往往無法反射內部的方法。為了實現這個,你需要操作字節碼,聽起來很可怕,但是是可行的。有一個叫 Morpheus 的庫,可以幫你做這些。

Q: 我嘗試過創建一個庫,遇到了一個路徑設置的問題,當時沒有辦法讓 Gradle 明白我是在創建庫而不是一個 App,你之前有見過這樣的問題么? Emauele: 遇見過,你需要正確使用 Google Android 的 Gradle 插件,探索一下他在哪里存儲你需要的信息,你需要對這個比較了解。

Q: 你更傾向用哪個 Jenkins 服務提供方?還是你通常在你本地運行? Emanule: 我通常自己跑他們。之所以這么做,是因為我搭建了一個沒有任何 executro 的 Master 機器,同時搭建了一堆本地 Slave 機器當做 Excutor,Master 機器可以使非常小的機器,不用那么強勁,無須處理任何編譯的事情。

責任編輯:未麗燕 來源: 由Realm提供的移動開發資訊
相關推薦

2017-05-19 16:40:41

AndroidKotlin開發者

2022-01-17 16:09:43

Go語言開發

2021-11-01 22:33:45

區塊鏈智慧城市元宇宙

2013-07-04 10:01:04

2013-03-12 14:30:09

Ubuntu操作系統

2016-01-08 10:17:10

Android開發

2015-08-06 10:14:15

造輪子facebook

2022-08-15 08:27:02

基站網絡

2012-07-04 09:55:55

Windows Pho

2020-06-22 07:18:21

Java語言開發

2018-05-23 00:20:29

2019-09-30 07:50:51

ITOps云端ITOM

2019-12-26 14:52:31

微軟CortanaAndroid

2016-08-19 16:27:52

數據庫Mongo DB開發

2017-04-05 18:10:05

R語言開發Ross

2021-03-16 08:35:14

Kubernetes Docker容器

2022-03-30 08:21:57

合并HTTP

2012-06-18 14:51:09

Python

2022-11-28 09:58:58

C++開發

2009-12-17 15:18:47

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文成人在线 | 一区二区片 | 国产98色在线 | 日韩 | 国产一区二区三区在线看 | 国产精品一区在线观看 | 久久精品免费观看 | 亚洲一区二区视频在线观看 | 久久精品小视频 | 国产成人免费 | 特级丰满少妇一级aaaa爱毛片 | 新av在线| 男人的天堂久久 | 日韩免费看片 | 伊人免费观看视频 | av一二三四 | 欧美一区二区三区在线观看 | 久久成人人人人精品欧 | 国产成人免费观看 | av毛片在线免费观看 | 亚洲视频免费在线看 | 亚洲综合一区二区三区 | 国产一区二区三区免费观看视频 | 国产精品3区 | 日韩精品一区二区三区中文字幕 | 日韩精品在线播放 | 北条麻妃av一区二区三区 | 国产精品国产三级国产aⅴ浪潮 | 国产精品99精品久久免费 | 亚洲精品日本 | 九九99靖品 | 亚洲日本欧美日韩高观看 | 成人在线观看免费视频 | 日韩一级免费大片 | 久久久青草婷婷精品综合日韩 | 婷婷久久网 | 欧美一级二级三级视频 | 国产欧美一区二区三区在线看蜜臀 | 黄色在线网站 | 91精品国产综合久久久久久 | 狠狠操av| 免费永久av |