主頁 > 移動端開發 > 位元組跳動技術整理:該如何高效實用Kotlin?附贈課程+題庫

位元組跳動技術整理:該如何高效實用Kotlin?附贈課程+題庫

2021-04-23 11:09:53 移動端開發

前言

工欲善其事必先利其器!在現代IT中,每個Android程式員都需要最好的工具來提高他們的技能和效率,在Android應用程式開發這個殘酷的競爭行業中,只有優秀的程式員才能生存下去,你需要向客戶展示你擁有的最佳技術和能力,

不僅僅是展示你的設備以吸引客戶,還要確保你的Android應用程式在高效的時間內以最高質量構建,那么哪些是最好的Android開發者工具?有很多選擇,但并非所有工具都足夠好,在不浪費任何時間的情況下,讓我們來看看以下的Android應用開發工具,

1、MVVM架構模式概覽

這是使用MVVM架構模式+Kotlin協程+JetPack(ViewModel+LiveData)+Retrofit的架構,實作WanAndroid登錄介面的小DEMO,后續會慢慢完善WanAndroid客戶端

1、ViewModel

為了從界面控制器Activity/Fragment邏輯中分離出視圖View資料所有權,架構組件為界面控制器提供了 ViewModel 輔助程式類,該類負責為界面準備資料,在配置更改期間會自動保留 ViewModel 物件,以便它們存盤的資料立即可供下一個 Activity 或 Fragment 實體使用,

2、LiveData

LiveData 是一種可觀察的資料存盤器類,具有生命周期感知能力,意指它遵循其他應用組件如 Activity、Fragment 或 Service 生命周期,可確保 LiveData 僅更新處于活躍生命周期狀態的應用組件觀察者,LiveData 物件通常存盤在 ViewModel 物件中,并可通過 getter 方法進行訪問,

3、Kotlin協程

協程依附在執行緒上,可以實作順序撰寫異步代碼,自動進行執行緒切換,并且ViewModelScope為應用中的每個 ViewModel 定義了 ViewModelScope,如果 ViewModel 已清除,則在此范圍內啟動的協程都會自動取消,

4、Retrofit

將服務介面中的網路請求函式宣告為suspend掛起介面函式,以支持Kotlin執行緒,并將suspend函式結果作為 LiveData 物件傳送,

2、ViewModel

//獲取ViewModel
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)` 

ViewModel 物件存在的時間范圍是獲取 ViewModel 時傳遞給 ViewModelProvider 的 Lifecycle,ViewModel 將一直留在記憶體中,直到限定其存在時間范圍的 Lifecycle 永久消失:對于 Activity,是在 Activity 完成時;而對于 Fragment,是在 Fragment 分離時,

3、LiveData

//對User資料進行觀察
viewModel.user.observe(this, Observer {
    //展示登錄結果
    if (it.errorCode == 0) {
        Toast.makeText(this, it.data?.nickname, Toast.LENGTH_SHORT).show()
    } else {
        Toast.makeText(this, it.errorMsg, Toast.LENGTH_SHORT).show()
    }
})

使用 LiveData 具有以下優勢:確保界面符合資料狀態

LiveData 遵循觀察者模式,當生命周期狀態發生變化時,LiveData 會通知 Observer 物件,您可以整合代碼以在這些 Observer 物件中更新界面,觀察者可以在每次發生更改時更新界面,而不是在每次應用資料發生更改時更新界面,

不會發生記憶體泄漏

觀察者會系結到 Lifecycle 物件,并在其關聯的生命周期遭到銷毀后進行自我清理,

不會因 Activity 停止而導致崩潰

如果觀察者的生命周期處于非活躍狀態(如回傳堆疊中的 Activity),則它不會接收任何 LiveData 事件,
不再需要手動處理生命周期
界面組件只是觀察相關資料,不會停止或恢復觀察,LiveData 將自動管理所有這些操作,因為它在觀察時可以感知相關的生命周期狀態變化,

資料始終保持最新狀態

如果生命周期變為非活躍狀態,它會在再次變為活躍狀態時接收最新的資料,例如,曾經在后臺的 Activity 會在回傳前臺后立即接收最新的資料,

適當的配置更改

如果由于配置更改(如設備旋轉)而重新創建了 Activity 或 Fragment,它會立即接收最新的可用資料,

共享資源

可以使用單一實體模式擴展 LiveData 物件以封裝系統服務,以便在應用中共享它們,

4、Kotlin協程

4.1、異步的本質

什么是異步?

異步就是同時進行一個以上彼此目的不同的任務,

但是對于有前后依賴關系的任務,異步該如何處理呢?

利用異步中的回呼機制處理,

為什么需要異步回呼機制?

因為不同的任務之間存在前后的依賴關系,

異步回呼機制有什么缺點?

代碼結構過分耦合,遇到多重函式回呼的嵌套耦合,也就是回呼地獄,代碼會難以維護,

解決回呼地獄的方案有什么?

鏈式呼叫結構,
常見方式就是使用RxJava,它是反應函式式編程在Java中的實作,
但是RxJava中流的創建、轉化與消費都需要使用到各種類和豐富的運算子,加大了RxJava的學習成本,
減少在無封裝情況下使用RxJava,因為你無法保證團隊里面的每一個成員都能看懂它,并且在修改時都能做出正確選擇,

在串行的執行中,雖然代碼確實是順序執行的,但其實是在不同的執行緒上順序執行的,那為什么在串行的執行中代碼執行順序一致,卻還要使用回呼呢?

因為串行的執行中,執行是阻塞式的,主執行緒的阻塞會導致很嚴重的問題,所以所有的耗時操作不能在主執行緒中執行,所以就需要多執行緒并行來執行,

在并行的執行中,異步回呼其實就是代碼的多執行緒順序執行,那能不能既按照順序的方式撰寫代碼,又可以讓代碼在不同的執行緒順序執行,自動完成執行緒的切換作業呢?

那就是Kotlin協程,
Kotlin 的協程是一種無堆疊協程的實作,它的控制流轉依靠對協程體本身編譯生成的狀態機的狀態流轉來實作,變數保存也是通過閉包語法來實作的,

結論:

異步回呼就是代碼的多執行緒順序執行,而Kotlin協程可以實作順序撰寫異步代碼,自動進行執行緒切換,

那么協程自動進行執行緒切換的原理是什么?

Yield:讓出CPU,放棄調度控制權,回到上一次Resume的地方
Resume:獲取調度控制權,繼續執行程式,到上一次Yield的地方

例子:

1. GlobalScope.launch發起了一個協程,并在IO執行緒上執行,
2\. 在協程里,去呼叫介面獲取結果,
3. 拿到結果,使用withContext(Dispatchers.Main)切換到主執行緒并更新界面

4.2、協程的型別

是協程范圍,指的是協程內的代碼運行的時間周期范圍,如果超出了指定的協程范圍,協程會被取消執行,

GlobalScope

指的是與應用行程相同的協程范圍,也就是在行程沒有結束之前協程內的代碼都可以運行,

JetPack中提供的生命周期感知型協程范圍:

ViewModelScope,為應用中的每個 ViewModel 定義了 ViewModelScope,如果 ViewModel 已清除,則在此范圍內啟動的協程都會自動取消,

LifecycleScope,為每個 Lifecycle 物件定義了 LifecycleScope,在此范圍內啟動的協程會在 Lifecycle 被銷毀時取消,

使用 LiveData 時,可能需要異步計算值,可以使用 liveData 構建器函式呼叫 suspend 函式,并將結果作為 LiveData 物件傳送,

相關鏈接:https://developer.android.google.cn/topic/libraries/architecture/coroutines

4.3、協程的啟動

launch方法:

/**
 * 重要知識:ViewModel+協程
 */
fun ViewModel.launch(
    block: suspend CoroutineScope.() -> Unit,
    one rror: (e: Throwable) -> Unit = {},
    onComplete: () -> Unit = {}
) {
    viewModelScope.launch(CoroutineExceptionHandler { _, e -> one rror(e) }) {
        try {
            block.invoke(this)
        } finally {
            onComplete()
        }
    }
}

原始碼:

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}

4.3.1、launch方法解釋

context

協程背景關系,可以指定協程運行的執行緒,默認與指定的CoroutineScope中的coroutineContext保持一致,比如GlobalScope默認運行在一個后臺作業執行緒內,也可以通過顯示指定引數來更改協程運行的執行緒,Dispatchers提供了幾個值可以指定:Dispatchers.Default、Dispatchers.Main、Dispatchers.IO、Dispatchers.Unconfined,

start

協程的啟動模式,默認的CoroutineStart.DEFAULT是指協程立即執行,除此之外還有CoroutineStart.LAZY、CoroutineStart.ATOMIC、CoroutineStart.UNDISPATCHED,

block

協程主體,也就是要在協程內部運行的代碼,可以通過lamda運算式的方式方便的撰寫協程內運行的代碼,

CoroutineExceptionHandler

指定CoroutineExceptionHandler來處理協程內部的例外,

Job

回傳值,對當前創建的協程的參考,可以通過Job的start、cancel、join等方法來控制協程的啟動和取消,

4.4、suspend掛起函式

suspend關鍵字只起到了標志這個函式是一個耗時操作,必須放在協程中執行的作用,而withContext方法則進行了執行緒的切換作業,

協程中的代碼自動地切換到其他執行緒之后又自動地切換回了主執行緒!順序撰寫保證了邏輯上的直觀性,協程的自動執行緒切換又保證了代碼的非阻塞性,掛起函式必須在協程或者其他掛起函式中被呼叫,也就是掛起函式必須直接或者間接地在協程中執行,

那為什么協程中的代碼沒有在主執行緒中執行呢?而且執行完畢為什么還會自動地切回主執行緒呢?

協程的掛起可以理解為協程中的代碼離開協程所在執行緒的程序,協程的恢復可以理解為協程中的代碼重新進入協程所在執行緒的程序,協程就是通過的這個掛起恢復機制進行執行緒的切換,

4.5、async await方法

用async方法包裹了suspend方法來執行并發請求,并發結果都回傳之后,切換到主執行緒,接著再用await方法來獲取并發請求結果,

5、Retrofit

HTTP介面suspend掛起函式:

interface ApiService {
    @FormUrlEncoded
    @POST("user/login")
    suspend fun loginForm(@Field("username")  username: String,@Field("password")  password: String): BaseResponse<User>
}

kotlin泛型:

data class BaseResponse<T>(
    val errorCode: Int=0,
    val errorMsg:String? = null,
    var data: T? = null
)

這是使用MVVM架構模式+Kotlin協程+JetPack(ViewModel+LiveData)+Retrofit的架構,實作WanAndroid登錄介面的小DEMO,后續會慢慢完善WanAndroid客戶端

最后相關架構及資料領取方式:

點擊我的騰訊檔案免費領取獲取往期Android高級架構資料、原始碼、筆記、視頻,高級UI、性能優化、架構師課程、NDK、混合式開發(ReactNative+Weex)微信小程式、Flutter全方面的Android進階實踐技術,群內還有技術大牛一起討論交流解決問題,

otlin協程+JetPack(ViewModel+LiveData)+Retrofit的架構,實作WanAndroid登錄介面的小DEMO,后續會慢慢完善WanAndroid客戶端

最后相關架構及資料領取方式:

點擊我的騰訊檔案免費領取獲取往期Android高級架構資料、原始碼、筆記、視頻,高級UI、性能優化、架構師課程、NDK、混合式開發(ReactNative+Weex)微信小程式、Flutter全方面的Android進階實踐技術,群內還有技術大牛一起討論交流解決問題,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/279285.html

標籤:其他

上一篇:鴻蒙Harmony應用(java)開發之初體驗。

下一篇:Kotlin實作Android頂部導航欄與模塊聯動

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more