前言
學(xué)習(xí)Kotlin
有一段時(shí)間了,想寫一個(gè)項(xiàng)目總結(jié)收獲格二,就有了這個(gè)可能是東半球最簡(jiǎn)潔的玩安卓客戶端,在此感謝玩Android 的開(kāi)放API巨税。
簡(jiǎn)介
適合初學(xué)者入門的項(xiàng)目蟋定,通過(guò)對(duì)Kotlin的系統(tǒng)運(yùn)用,實(shí)現(xiàn)的一個(gè)功能完備符合主流市場(chǎng)標(biāo)準(zhǔn)App草添。
雖然本項(xiàng)目的定位是入門級(jí)驶兜,但是該有的知識(shí)點(diǎn)卻一點(diǎn)不少,對(duì)理解其他項(xiàng)目設(shè)計(jì)思想和封裝技巧也很有幫助远寸。
學(xué)習(xí)本項(xiàng)目你將有如下收獲:
- Kotlin實(shí)戰(zhàn)(函數(shù)進(jìn)階抄淑,泛型,反射驰后,協(xié)程...)
- MVVM開(kāi)發(fā)架構(gòu)(ViewBinding肆资,ViewModel,LiveData灶芝,RoomDatabase...)
- 單Activity多Fragment項(xiàng)目設(shè)計(jì)
- 暗夜模式
- 屏幕錄制
- 字節(jié)碼插樁
截圖展示
1.jpg
|
2.jpg
|
3.jpg
|
---|---|---|
4.jpg
|
5.jpg
|
6.jpg
|
項(xiàng)目目錄結(jié)構(gòu)
├── app app
| └── src
| └── main
| | └── java 源碼目錄
| | ├── activity Activity目錄
| | | └── MainActivity 項(xiàng)目唯一Activity
| | ├── adapter Adapter目錄
| | ├── fragment Fragment目錄
| | ├── model ViewModel目錄
| | └── App Application
| |
| └── build.gradle 模塊構(gòu)建配置
| └── channel 渠道配置文件
| └── dictionary 自定義混淆字典
| └── proguard-rules.pro 代碼混淆配置文件
|
├── library_base 基礎(chǔ)library(存放通用的封裝源碼)
| └── src
| └── main
| | ├── assets 原生文件目錄
| | └── java 源碼目錄
| | ├── bus 消息總線目錄
| | ├── dialog Dialog目錄
| | ├── http 網(wǎng)絡(luò)請(qǐng)求目錄
| | ├── provider ContentProvider目錄
| | ├── utils 工具類目錄
| | └── view 自定義view目錄
| |
| └── build.gradle 模塊構(gòu)建配置
|
├── library_common 公共library(存放各個(gè) module 公共的源碼及資源)
| └── src
| └── main
| | └── java 源碼目錄
| | ├── bean 實(shí)體類目錄
| | └── constant 常量配置目錄
| |
| └── build.gradle 模塊構(gòu)建配置
|
├── module_faq 問(wèn)答模塊(目錄同app郑原,不再展開(kāi))
├── module_home 首頁(yè)模塊(目錄同app唉韭,不再展開(kāi))
├── module_navigation 導(dǎo)航模塊(目錄同app,不再展開(kāi))
├── module_project 項(xiàng)目模塊(目錄同app犯犁,不再展開(kāi))
├── module_system 體系模塊(目錄同app属愤,不再展開(kāi))
├── module_user 用戶模塊(目錄同app,不再展開(kāi))
|
├── plugin_statistic 統(tǒng)計(jì)插件模塊
| └── src
| └── main
| └── groovy 源碼目錄
| | ├── bp 埋點(diǎn)統(tǒng)計(jì)目錄
| | └── mt 耗時(shí)統(tǒng)計(jì)目錄
| |
| └── resources 配置目錄
| └── statistic.properties 插件配置
|
├── repos 統(tǒng)計(jì)插件生成目錄
|
├── build.gradle 項(xiàng)目構(gòu)建配置
├── config.gradle gradle編譯文件 gradle依賴配置
├── config.properties 項(xiàng)目配置
├── gradle.properties gradle配置
└── settings.gradle 項(xiàng)目依賴配置
ViewBinding
通過(guò)視圖綁定功能酸役,您可以更輕松地編寫可與視圖交互的代碼住诸。在模塊中啟用視圖綁定之后,系統(tǒng)會(huì)為該模塊中的每個(gè) XML 布局文件生成一個(gè)綁定類涣澡。綁定類的實(shí)例包含對(duì)在相應(yīng)布局中具有 ID 的所有視圖的直接引用贱呐。
與使用 findViewById 相比,視圖綁定具有 Null 安全入桂,類型安全等很顯著的優(yōu)點(diǎn)奄薇。
LiveData
LiveData 是一種可觀察的數(shù)據(jù)存儲(chǔ)器類,它具有生命周期感知能力事格,意指它遵循其他應(yīng)用組件(如 Activity惕艳、Fragment 或 Service)的生命周期。
LiveData 的優(yōu)勢(shì):不會(huì)發(fā)生內(nèi)存泄漏驹愚,不會(huì)因 Activity 停止而導(dǎo)致崩潰远搪,不再需要手動(dòng)處理生命周期,數(shù)據(jù)始終保持最新?tīng)顟B(tài)逢捺,適當(dāng)?shù)呐渲酶乃ⅲ蚕碣Y源。
ViewModel
ViewModel 類旨在以注重生命周期的方式存儲(chǔ)和管理界面相關(guān)的數(shù)據(jù)劫瞳。ViewModel 類讓數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后繼續(xù)留存倘潜。
協(xié)程
協(xié)程是一種并發(fā)設(shè)計(jì)模式,您可以使用它來(lái)簡(jiǎn)化異步執(zhí)行的代碼志于。
協(xié)程的特點(diǎn)包括:輕量涮因,內(nèi)存泄漏更少,內(nèi)置取消支持伺绽,Jetpack 集成养泡。
Fragment + LiveData + ViewModel + 協(xié)程
以項(xiàng)目中 MainFragment 為例:
class MainViewModel : ViewModel() {
val hotKeyResult = MutableLiveData<HotKeyListBean>()
// 獲取熱詞接口
fun getHotKey() {
// 通過(guò)viewModelScope創(chuàng)建一個(gè)協(xié)程
viewModelScope.launch {
// 構(gòu)建請(qǐng)求體,傳入請(qǐng)求參數(shù)
val request = HttpRequest("hotkey/json")
// 以get方式發(fā)起網(wǎng)絡(luò)請(qǐng)求
val response = get<HotKeyListBean>(request)
// 通過(guò)LiveData更新數(shù)據(jù)
hotKeyResult.postValue(response)
}
}
}
class MainFragment : Fragment() {
// 使用 'by viewModels()' Kotlin屬性委托獲取 MainViewModel
private val viewModel: MainViewModel by viewModels()
private val hotKeyAdapter = HotKeyAdapter()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 觀察 hotKeyResult 的變化來(lái)更新UI
viewModel.hotKeyResult.observe(viewLifecycleOwner, { result ->
result.data?.apply {
if (result.errorCode == "0") {
hotKeyAdapter.setNewData(this)
}
}
})
// 調(diào)用獲取熱詞接口
viewModel.getHotKey()
}
}
基于LiveData封裝的消息總線LiveDataBus
LiveDataBus具有生命周期感知奈应,調(diào)用者不需要調(diào)用反注冊(cè)澜掩,并且沒(méi)有內(nèi)存泄漏風(fēng)險(xiǎn)。
1杖挣、發(fā)送事件
LiveDataBus.with<String>("key").postEvent("value")
2肩榕、接收事件
LiveDataBus.with<String>("key").observe(viewLifecycleOwner, { it ->
println(it)
})
3、接收粘滯事件
LiveDataBus.with<String>("key").observeSticky(viewLifecycleOwner, { it ->
println(it)
})
基于RoomDatabase封裝的DBHelper
通過(guò)鍵值對(duì)的方式來(lái)存儲(chǔ)數(shù)據(jù)惩妇,不用再去關(guān)心RoomDatabase的復(fù)雜操作株汉。
1筐乳、存儲(chǔ)數(shù)據(jù)
DBHelper.set(“key”, "value")
2、獲取數(shù)據(jù)
DBHelper.get(“key”)
字節(jié)碼插樁
相關(guān)知識(shí)已發(fā)布在簡(jiǎn)書上郎逃,可點(diǎn)擊下面鏈接跳轉(zhuǎn)查看
- 最通俗易懂的字節(jié)碼插樁實(shí)戰(zhàn)(Gradle + ASM)—— 優(yōu)雅的打印方法執(zhí)行時(shí)間
- 最通俗易懂的字節(jié)碼插樁實(shí)戰(zhàn)(Gradle + ASM)—— 自動(dòng)埋點(diǎn)
主要開(kāi)源框架
Thanks
感謝所有優(yōu)秀的開(kāi)源項(xiàng)目 _
如果喜歡的話希望給個(gè) Star 或 Fork _
謝謝~~