在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用Kotlin替代Java重構AOSP應用

谷歌開發者 ? 來源:Android開發者 ? 作者:Android ? 2021-09-16 09:26 ? 次閱讀

兩年前,Android 開源項目 (AOSP) 應用團隊開始使用 Kotlin 替代 Java 重構 AOSP 應用。之所以重構主要有兩個原因: 一是確保 AOSP 應用能夠遵循 Android 最佳實踐,另外則是提供優先使用 Kotlin 進行應用開發的良好范例。Kotlin 之所以具有強大的吸引力,原因之一是其簡潔的語法,很多情況下用 Kotlin 編寫的代碼塊的代碼數量相比于功能相同的 Java 代碼塊要更少一些。此外,Kotlin 這種具有豐富表現力的編程語言還具有其他各種優點,例如:

空安全: 這一概念可以說是根植于 Kotlin 之中,從而幫助避免破壞性的空指針異常;

并發: 正如 Google I/O 2019 中關于 Android 的描述,結構化并發 (structured concurrency) 能夠允許使用協程簡化后臺的任務管理;

兼容 Java: 尤其是在這次的重構項目中,Kotlin 與 Java 語言的兼容性能夠讓我們一個文件一個文件地進行 Kotlin 轉換。

Android 開源項目 (AOSP) 應用

https://android.googlesource.com/platform/packages/apps/

Kotlin

https://kotlinlang.org/

Google I/O 2019

https://developer.android.google.cn/kotlin/first

AOSP 團隊在去年夏天發表了一篇文章,詳細介紹了 AOSP 桌面時鐘應用的轉換過程。而今年,我們將 AOSP 日歷應用從 Java 轉換成了 Kotlin。在這次轉換之前,應用的代碼行數超過 18,000 行,在轉換后代碼庫減少了約 300 行。在這次的轉換中,我們沿襲了同 AOSP 桌面時鐘轉換過程中類似的技術,充分利用了 Kotlin 與 Java 語言的互操作性,對代碼文件一一進行了轉換,并在過程中使用獨立的構建目標將 Java 代碼文件替換為對應的 Kotlin 代碼文件。因為團隊中有兩個人在進行此項工作,所以我們在 Android.bp 文件中為每個人創建了一個 exclude_srcs 屬性,這樣兩個人就可以在減少代碼合并沖突的前提下,都能夠同時進行重構并推送代碼。此外,這樣還能允許我們進行增量測試,快速定位錯誤出現在哪些文件。

AOSP 桌面時鐘應用的轉換過程

https://medium.com/androiddevelopers/re-writing-the-aosp-deskclock-app-in-kotlin-76c836370cb

在轉換任意給定的文件時,我們一開始先使用 Android Studio Kotlin 插件中提供的從 Java 到 Kotlin 的自動轉換工具。雖然該插件成功幫助我們轉換了大部份的代碼,但是還是會遇到一些問題,需要開發者手動解決。需要手動更改的部分,我們將會在本文接下來的章節中列出。

在將每個文件轉換為 Kotlin 之后,我們手動測試了日歷應用的 UI 界面,運行了單元測試,并運行了 Compatibility Test Suite (CTS) 的子集來進行功能驗證,以確保不需要再進行任何的回歸測試。

Android Studio

https://developer.android.google.cn/studio

從 Java 到 Kotlin 的自動轉換工具

https://developer.android.google.cn/kotlin/add-kotlin#convert

Compatibility Test Suite (CTS)

https://source.android.google.cn/compatibility/cts

自動轉換之后的步驟

上面提到,在使用自動轉換工具之后,有一些反復出現的問題需要手動定位解決。在 AOSP 桌面時鐘文章中,詳細介紹了其中遇到的一些問題以及解決方法。如下列出了一些在進行 AOSP 日歷轉換過程中遇到的問題。

用 open 關鍵詞標記父類

我們遇到的問題之一是 Kotlin 父類和子類之間的相互調用。在 Kotlin 中,要將一個類標記為可繼承,必須得在類的聲明中添加 open 關鍵字,對于父類中被子類覆蓋的方法也要這樣做。但是在 Java 中的繼承是不需要使用到 open 關鍵字的。由于 Kotlin 和 Java 能夠相互調用,這個問題直到大部分代碼文件轉換到了 Kotlin 才出現。

例如,在下面的代碼片段中,聲明了一個繼承于 SimpleWeeksAdapter 的類:

class MonthByWeekAdapter(context: Context?, params: HashMap《String?, Int?》) : SimpleWeeksAdapter(context as Context, params) {//方法體}

由于代碼文件的轉換過程是一次一個文件進行的,即使是完全將 SimpleWeeksAdapter.kt 文件轉換成 Kotlin,也不會在其類的聲明中出現 open 關鍵詞,這樣就會導致一個錯誤。所以之后需要手動進行 open 關鍵詞的添加,以便讓 SimpleWeeksAdapter 類可以被繼承。這個特殊的類聲明如下所示:

open class SimpleWeeksAdapter(context: Context, params: HashMap《String?, Int?》?) {//方法體}

override 修飾符

同樣地,子類中覆蓋父類的方法也必須使用 override 修飾符來進行標記。在 Java 中,這是通過 @Override 注解來實現的。然而,雖然在 Java 中有相應的注解實現版本,但是自動轉換過程中并沒有為 Kotlin 方法聲明中添加 override 修飾符。解決的辦法是在所有適當的地方手動添加 override 修飾符。

覆寫父類中的屬性

在重構過程中,我們還遇到了一個屬性覆寫的異常問題,當一個子類聲明了一個變量,而在父類中存在一個非私有的同名變量時,我們需要添加一個 override 修飾符。然而,即使子類的變量同父類變量的類型不同,也仍然要添加 override 修飾符。在某些情況下,添加 override 仍不能解決問題,尤其是當子類的類型完全不同的時候。事實上,如果類型不匹配,在子類的變量前添加 override 修飾符,并在父類的變量前添加 open 關鍵字,會導致一個錯誤:

type of *property name* doesn’t match the type of the overridden var-property

這個報錯很讓人疑惑,因為在 Java 中,以下代碼可以正常編譯:

public class Parent { int num = 0;}

class Child extends Parent { String num = “num”;}

而在 Kotlin 中相應的代碼就會報上面提到的錯誤:

class Parent { var num: Int = 0}

class Child : Parent() { var num: String = “num”}

這個問題很有意思,目前我們通過在子類中對變量重命名來規避了這個沖突。上面的 Java 代碼會被 Android Studio 目前提供的代碼轉換器轉換為有問題的 Kotlin 代碼,這甚至被報告為是一個 bug 了。

被報告為是一個 bug

https://youtrack.jetbrains.com/issue/KTIJ-8621

import 語句

在我們轉換的所有文件中,自動轉換工具都傾向于將 Java 代碼中的所有 import 語句截斷為 Kotlin 文件中的第一行。最開始這導致了一些很讓人抓狂的錯誤,編譯器會在整個代碼中報 “unknown references” 的錯誤。在意識到這個問題后,我們開始手動地將 Java 中的 import 語句粘貼到 Kotlin 代碼文件中,并單獨對其進行轉換。

暴露成員變量

默認情況下,Kotlin 會自動地為類中的實例變量生成 getter 和 setter 方法。然而,有些時候我們希望一個變量僅僅只是一個簡單的 Java 成員變量,這可以通過使用 @JvmField 注解來實現。

@JvmField 注解的作用是 “指示 Kotlin 編譯器不要為這個屬性生成 getter 和 setter 方法,并將其作為一個成員變量允許其被公開訪問”。這個注解在 CalendarData 類中特別有用,它包含了兩個 static final 變量。通過對使用 val 聲明的只讀變量使用 @JvmField 注解,我們確保了這些變量可以作為成員變量被其他類訪問,從而實現了 Java 和 Kotlin 之間的兼容性。

@JvmField 注解

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-field/

CalendarData 類

https://android.googlesource.com/platform/packages/apps/Calendar/+/42e4b43133c4f866e0729438fb38bebc6d03b0a4/src/com/android/calendar/CalendarData.kt

val

https://kotlinlang.org/docs/basic-syntax.html#variables

對象中的靜態方法

在 Kotlin 對象中定義的函數必須使用 @JvmStatic 進行標記,以允許在 Java 代碼中通過方法名,而非實例化來對它們進行調用。也就是說,這個注解使其具有了類似 Java 的方法行為,即能夠通過類名調用方法。根據 Kotlin 的文檔,“編譯器會為對象的外部類生成一個靜態方法,而對于對象本身會生成一個實例方法。”我們在 Utils 文件中遇到了這個問題,當完成轉換后,Java 類就變成了 Kotlin 對象。隨后,所有在對象中定義的方法都必須使用 @JvmStatic 標記,這樣就允許在其他文件中使用 Utils.method() 這樣的語法來進行調用。值得一提的是,在類名和方法名之間使用 .INSTANCE (即 Utils.INSTANCE.method()) 也是一種選擇,但是這不太符合常見的 Java 語法,需要改變所有對 Java 靜態方法的調用。

Kotlin 的文檔

https://kotlinlang.org/docs/java-to-kotlin-interop.html#static-methods

Utils 文件

https://android.googlesource.com/platform/packages/apps/Calendar/+/42e4b43133c4f866e0729438fb38bebc6d03b0a4/src/com/android/calendar/Utils.kt

性能評估分析

所有的基準測試都是在一臺 96 核、176 GiB 內存的機器上進行的。本項目中分析用到的主要指標有所減少的代碼行數、目標 APK 的文件大小、構建時間和首屏從啟動到顯示的時間。在對上述每個因素進行分析的同時,我們還收集了每個參數的數據并以表格的方式進行了展示。

減少的代碼行數

9a8bd36e-1657-11ec-8fb8-12bb97331649.png

從 Java 完全轉換到 Kotlin 后,代碼行數從 18,004 減少到了 17,729。這比原來的 Java 代碼量減少了大約 1.5%。雖然減少的代碼量并不可觀,但對于一些大型應用來說,這種轉換對于減少代碼行數的效果可能更為顯著,可參閱 AOSP 桌面時鐘文中所舉的例子。

AOSP 桌面時鐘https://medium.com/androiddevelopers/re-writing-the-aosp-deskclock-app-in-kotlin-76c836370cb

目標 APK 大小

9a975cfc-1657-11ec-8fb8-12bb97331649.png

使用 Kotlin 編寫的應用 APK 大小是 2.7 MB,而使用 Java 編寫的應用 APK 大小是 2.6 MB??梢哉f這個差異基本可以忽略不計了,由于包含了一些額外的 Kotlin 庫,所以 APK 體積上的增加,實際上是可以預期的。這種大小的增加可以通過使用 Proguard 或 R8 來進行優化。

Proguardhttps://developer.android.google.cn/studio/build/shrink-code

R8https://r8.googlesource.com/r8

編譯時間

9aa1be04-1657-11ec-8fb8-12bb97331649.png

Kotlin 和 Java 應用的構建時間是通過取 10 次從零進行完整構建的時間的平均值來計算的 (不包含異常值),Kotlin 應用的平均構建時間為 13 分 27 秒,而 Java 應用的平均構建時間為 12 分 6 秒。據一些資料 (如 “Java 和 Kotlin 的區別” 以及 “Kotlin 和 Java 在編譯時間上的對比”) 顯示,Kotlin 的編譯時間事實上比 Java 要更耗時,特別是對于從零開始的構建。一些分析斷言,Java 的編譯速度會快 10-15%,又有一些分析稱這一數據為 15-20%。拿我們的例子進行從零開始完整構建所花費的時間來說,Java 的編譯速度比 Kotlin 快 11.2%,盡管這個微小的差異并不在上述范圍內,但這有可能是因為 AOSP 日歷是一個相對較小的應用,僅有 43 個類。盡管從零開始的完整構建比較慢,但是 Kotlin 仍然在其他方面占有優勢,這些優勢更應該被考慮到。例如,Kotlin 相對于 Java,更簡潔的語法通常可以保證較少的代碼量,這使得 Kotlin 代碼庫更易維護。此外,由于 Kotlin 是一種更為安全有效的編程語言,我們可以認為完整構建時間較慢的問題可以忽略不計。

Java 和 Kotlin 的區別

https://www.educba.com/java-vs-kotlin/

Kotlin 和 Java 在編譯時間上的對比https://medium.com/keepsafe-engineering/kotlin-vs-java-compilation-speed-e6c174b39b5d

首屏顯示的時間

9aad76a4-1657-11ec-8fb8-12bb97331649.png

我們使用了這種方法來測試應用從啟動到完全顯示首屏所需要的時間,經過 10 次試驗后我們發現,使用 Kotlin 應用的平均時間約為 197.7 毫秒,而 Java 的則為 194.9 毫秒。這些測試都是在 Pixel 3a XL 設備上進行的。從這個測試結果可以得出結論,與 Kotlin 應用相比,Java 應用可能具有微小的優勢;然而,由于平均時間非常接近,這個差異幾乎可以忽略不計。因此,可以說 AOSP 日歷應用轉換到 Kotlin,并沒有對應用的初始啟動時間產生負面影響。

方法https://developer.android.google.cn/topic/performance/vitals/launch-time#time-initial

結論

將 AOSP 日歷應用轉換為 Kotlin 大約花了 1.5 個月 (6 周) 的時間,由 2 名實習生負責該項目的實施。一旦我們對代碼庫更加熟悉并更加善于解決反復出現的編譯時、運行時和語法問題時,效率肯定會變得更高??偟膩碚f,這個特殊的項目成功地展示了 Kotlin 如何影響現有的 Android 應用,并在對 AOSP 應用進行轉換的路途中邁出了堅實的一步。

歡迎您通過下方二維碼向我們提交反饋,或分享您喜歡的內容、發現的問題。您的反饋對我們非常重要,感謝您的支持!

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Android
    +關注

    關注

    12

    文章

    3964

    瀏覽量

    129567
  • JAVA
    +關注

    關注

    20

    文章

    2984

    瀏覽量

    106892
  • 代碼
    +關注

    關注

    30

    文章

    4887

    瀏覽量

    70260
  • AOSP
    +關注

    關注

    0

    文章

    16

    瀏覽量

    6346

原文標題:使用 Kotlin 重寫 AOSP 日歷應用

文章出處:【微信號:Google_Developers,微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    一種低翹曲扇出重構方案

    翹曲(Warpage)是結構固有的缺陷之一。晶圓級扇出封裝(FOWLP)工藝過程中,由于硅芯片需通過環氧樹脂(EMC)進行模塑重構成為新的晶圓,使其新的晶圓變成非均質材料,不同材料間的熱膨脹和收縮程度不平衡則非常容易使重構晶圓發生翹曲。
    的頭像 發表于 05-14 11:02 ?151次閱讀
    一種低翹曲扇出<b class='flag-5'>重構</b>方案

    Java開發者必備的效率工具——Perforce JRebel是什么?為什么很多Java開發者在用?

    Perforce JRebel是一款Java開發效率工具,旨在幫助java開發人員更快地編寫更好的應用程序。JRebel可即時重新加載對代碼的修改,無需重啟或重新部署應用程序,就能讓開發者即時看到代碼更改的效果,從而縮短開發、調試和測試周期,大大提升開發效率。
    的頭像 發表于 04-27 13:44 ?155次閱讀
    <b class='flag-5'>Java</b>開發者必備的效率工具——Perforce JRebel是什么?為什么很多<b class='flag-5'>Java</b>開發者在用?

    Java 到 Go:面向對象的巨人與云原生的輕騎兵

    Go 語言在 2009 年被 Google 推出,在創建之初便明確提出了“少即是多(Less is more)”的設計原則,強調“以工程效率為核心,用極簡規則解決復雜問題”。它與 Java 語言生態
    的頭像 發表于 04-25 11:13 ?168次閱讀

    Java應用OOM問題的排查過程

    導讀 本文記錄最近一例Java應用OOM問題的排查過程,希望可以給遇到類似問題的同學提供參考。 前言:此文記錄最近一例Java應用OOM問題的排查過程,希望可以給遇到類似問題的同學提供參考。在本地
    的頭像 發表于 02-12 11:15 ?560次閱讀
    <b class='flag-5'>Java</b>應用OOM問題的排查過程

    Java 23功能介紹

    Java 23 包含全新和更新的 Java 語言功能、核心 API 以及 JVM,同時適合新的 Java 開發者和高級開發者。從?IntelliJ IDEA 2024.2?開始已支持 Java
    的頭像 發表于 12-04 10:02 ?846次閱讀
    <b class='flag-5'>Java</b> 23功能介紹

    Java集合API的改進介紹

    解答這些問題。 我們將逐步學習 Java 集合類的優化過程,并按版本逐一對比分析。主要討論的焦點將包括 JDK 1.0、1.2、1.4、1.5、1.6、1.8、9、10、11 和 21 版本的 Java 集合功能 Java 集合
    的頭像 發表于 11-22 11:12 ?503次閱讀
    <b class='flag-5'>Java</b>集合API的改進介紹

    對比Python與Java編程語言

    Python與Java都是目前非常流行的編程語言,它們各有其獨特的優勢和適用場景。以下是對這兩種編程語言的對比: 一、語法和易用性 Python 語法簡潔,代碼更易讀,非常適合初學者。 動態類型系統
    的頭像 發表于 11-15 09:31 ?910次閱讀

    基于Java的工具Power Stage Designer

    電子發燒友網站提供《基于Java的工具Power Stage Designer.pdf》資料免費下載
    發表于 11-14 16:01 ?7次下載
    基于<b class='flag-5'>Java</b>的工具Power Stage Designer

    Android 16發布計劃曝光,谷歌將同步更新AOSP與Pixel設備

     據外媒最新報道,谷歌計劃在2025年6月3日邁出安卓系統更新的一大步,屆時將正式將Android 16推送至Android開放源代碼項目(AOSP),并同步為Pixel設備帶來這一全新系統的更新
    的頭像 發表于 11-06 17:05 ?1625次閱讀

    Java中時間戳的使用

    Java中時間戳的使用
    的頭像 發表于 11-06 16:04 ?461次閱讀
    <b class='flag-5'>Java</b>中時間戳的使用

    C語言與Java語言的對比

    C語言和Java語言都是當前編程領域中的重要成員,它們各自具有獨特的優勢和特點,適用于不同的應用場景。以下將從語法特性、內存管理、跨平臺性、性能、應用領域等多個方面對C語言和Java語言進行詳細對比。
    的頭像 發表于 10-29 17:31 ?938次閱讀

    java反編譯能拿到源碼嗎

    Java反編譯是一種將編譯后的Java字節碼(.class文件)轉換回Java源代碼的過程。雖然反編譯可以幫助理解代碼的邏輯和結構,但它并不總是能完美地還原原始源代碼。反編譯工具通常會產生與原始代碼
    的頭像 發表于 09-02 11:03 ?1664次閱讀

    重構:改善既有代碼的設計」實戰篇

    背景 在軟件開發的世界里,代碼重構是提升項目質量、適應業務變化的關鍵步驟。最近,我重新翻閱了《重構:改善既有代碼的設計 第二版》,這本書不僅重新點燃了我對重構的熱情,還深化了我的理解:重構
    的頭像 發表于 08-14 10:42 ?528次閱讀
    「<b class='flag-5'>重構</b>:改善既有代碼的設計」實戰篇

    代碼靜態測試工具Klocwork 2024.2新發布

    Klocwork 2024.2 為現代?C/C++?分析引擎引入了顯著的準確性和性能改進。此版本還包括增強的安全性和身份驗證功能以及改進的用戶體驗,以及?MISRA??和?CERT?規則集改進、Java?語言增強功能以及?Kotlin?的新?CWE?映射。
    的頭像 發表于 08-06 12:16 ?511次閱讀
    代碼靜態測試工具Klocwork 2024.2新發布

    華納云:java web和java有什么區別java web和java有什么區別

    Java Web和Java是兩個不同的概念,它們在功能、用途和實現方式上存在一些區別,下面將詳細介紹它們之間的區別。 1. 功能和用途: – Java是一種編程語言,它提供了一種用于開發各種應用程序
    的頭像 發表于 07-16 13:35 ?1365次閱讀
    華納云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區別<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區別
    主站蜘蛛池模板: 白浆喷射 | 手机福利在线观看 | 日韩一卡 二卡 三卡 四卡 免费视频 | 免费爱爱视频网站 | 国模大尺度酒店私拍视频拍拍 | 亚洲第一香蕉视频 | 久久xx| 欧美日韩在线成人免费 | 一区二区三区中文字幕 | 嫩草影院www | qvod高清在线成人观看 | 美女视频网站色 | 午夜 福利 视频 | 国产香港三级理论在线 | 一区二区三区亚洲视频 | 羞羞色院91精品网站 | 色拍视频| 日韩一级黄色录像 | 在线www天堂资源网 在线播放 你懂的 | 亚洲开心激情网 | 国产美女视频一区二区二三区 | 午夜性影院 | 天天干夜夜欢 | 成人国产一区 | 天天插天天射 | 日日碰狠狠添天天爽五月婷 | 黄色三级国产 | 操你啦网站 | 777影院| 人人狠狠综合88综合久久 | 欧美影欧美影院免费观看视频 | 亚洲视频 欧美视频 | 综合网天天操天天射 | 婷婷亚洲综合 | ts 人妖 另类 在线 | 日韩综合色| 拍拍拍无档又黄又爽视频 | www激情com| 全国男人的天堂网站 | 五月婷婷六月爱 | 成人三级在线观看 |