前言
學習了Kotlin有一段時間了, 每次寫專案/Demo
的時候, 總是用到網路請求
、MVP
、MVVM
、常用工具類
、通用自定義View
, 索性把這些整合到一起, 搭成一個Android的腳手架——KtArmor
.
什麼是KtArmor ?
KtArmor
寓意著 為Android 賦予戰鬥裝甲
, 方便開發者快速進行Android 開發。節約開發者開發時間。為了滿足開發者需求, 我整合了兩個分支, 分別對應著 MVP
, MVVM
.
- MVP分支
- 架構模式:
MVP
+Kotlin
- 網路請求:
Retrofit
+Okhttp
+Coroutine
+RxJava
- 功能
- 基本
BaseActivity
、BaseFragment
、ToolbarActivity
封裝 - MVP框架封裝
MvpActivity
、MvpFragment
、BasePresenter
、BaseModel
封裝 - 網路請求封裝
BaseOkHttpClient
、BaseRetrofit
、RetrofitFactory
- 常用控制元件
PlaceHolderView(佔位佈局)
,LoadingView(載入框)
- 常用擴充套件封裝(
SharedPreferences
、StartActivity
、Log
、Toast
(不重複顯示))等 - MVP程式碼模板(
Activity
、Presenter
、Contract
、Model
)生成外掛 - ....
- 基本
- 架構模式:
- MVVM分支
架構模式:MVVM
+Androidx
+Kotlin
+LiveData
+ViewModel
網路請求:Coroutines
+Retrofit
+Okhttp
MVP框架引入
先在 build.gradle(Project:XXXX) 的 repositories 新增:
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
複製程式碼
然後在 build.gradle(Module:app) 的 dependencies 新增:
implementation 'com.github.hyzhan43:KtArmor:mvp-1.0.4' // 根據github 引入最新版本即可
複製程式碼
快速上手
在Application 中初始化KtArmor
框架。新建一個application 類, 如 BaseApplication, 在 BaseApplication 中, 呼叫KtArmor的 init
方法, 進行初始化, 引數如下:
- 第一個引數是
application
, - 第二個引數是對應
RetrofitConfig
配置。
class BaseApplication: Application(){
override fun onCreate() {
super.onCreate()
// 初始化KtArmor
KtArmor.init(this, MyRetrofitConfig())
}
}
複製程式碼
再新建一個 RetrofitConfig 配置類, 繼承 BaseRetrofitConfig
. 並複寫 baseUrl
屬性, 新增自己的 baseUrl。
class MyRetrofitConfig : BaseRetrofitConfig() {
override val baseUrl: String
get() = API.BASE_URL
}
複製程式碼
這樣你就建立好了一個擁有Kotlin
+ Retrofit
+ Okhttp
+ Coroutine
專案了。然後就可以愉快編寫自己的業務程式碼了(●'◡'●)
Login 示例
1、LoginContract
我們先從簡單登入流程來熟悉一下KtArmor。首先編寫 LoginContract, 程式碼如下:
interface LoginContract {
interface View : BaseContract.View {
fun accountEmpty(msg: Int)
fun passwordEmpty(msg: Int)
fun loginSuc(loginRsp: LoginRsp)
}
interface Presenter : BaseContract.Presenter {
fun login(account: String, password: String)
}
}
複製程式碼
2、LoginActivity
然後新建一個LoginActivity, 繼承 MvpActivity
並傳遞對應 LoginContract.Presenter
泛型,實現 LoginContract.View
介面, 程式碼如下:
class LoginActivity : MvpActivity<LoginContract.Presenter>(), LoginContract.View {
override fun getLayoutId(): Int = R.layout.activity_login
override fun bindPresenter(): LoginContract.Presenter = LoginPresenter(this)
override fun initListener() {
super.initListener()
mBtnLogin.setOnClickListener {
mTilAccount.isErrorEnabled = false
mTilPassword.isErrorEnabled = false
// 發起登入請求
presenter.login(mEtAccount.str(), mEtPassword.str())
}
}
override fun accountEmpty(msg: Int) {
mTilAccount.isErrorEnabled = true
mTilAccount.requestFocus()
mTilAccount.error = getString(msg)
}
override fun passwordEmpty(msg: Int) {
mTilPassword.isErrorEnabled = true
mTilPassword.requestFocus()
mTilPassword.error = getString(msg)
}
override fun loginSuc(loginRsp: LoginRsp) {
toast("登陸成功!")
}
}
複製程式碼
- bindPresenter 方法返回 LoginPresenter 例項。
- getLayoutId方法 返回LoginActivity 佈局id。
這裡 activity_login 裡面是簡單的 TextInputEditText,呼叫presenter, 發起登入請求。傳遞賬號和密碼。其中 str() 為 TextView 擴充套件方法。
str()
為擴充套件方法
// 獲取text內容
fun TextView.str(): String {
return this.text.toString()
}
複製程式碼
3、LoginPresenter
然後我們再看看對應 LoginPresenter 實現, 繼承 BasePresenter
,並傳遞對應 LoginContract.View
class LoginPresenter(view: LoginContract.View) : BasePresenter<LoginContract.View>(view), LoginContract.Presenter {
override fun login(account: String, password: String) {
if (account.isEmpty()) {
view?.accountEmpty(R.string.account_empty)
return
}
if (password.isEmpty()) {
view?.passwordEmpty(R.string.password_empty)
return
}
launchUI({
view?.showLoading()
val response = LoginModel.login(account, password)
// 正常返回結果處理
if (response.isSuccess()) {
response.data?.let { view?.loginSuc(it) }
} else {
view?.showError(response.errorMsg)
}
}, {
// TODO 異常處理
})
}
}
複製程式碼
在這裡, 我們採用協程
來實現切換執行緒操作。在 launchUI() 方法裡面啟動了一個 UI 協程,在這裡呼叫 LoginModel 真正發起網路請求操作。
4、LoginModel
object LoginModel : BaseModel() {
suspend fun login(account: String, password: String): BaseResponse<LoginRsp> {
return launchIO { ApiManager.apiService.loginAsync(account, password).await() }
}
}
複製程式碼
同樣,LoginModel 需要繼承 BaseModel()
,並呼叫 launchIO 進行執行緒切換。切換到 IO執行緒 通過ApiManager.apiService 發起網路請求。然後呼叫 await() 返回結果。這裡 ApiService 通過 RetrofitFactory建立, 傳入 Service class。
object ApiManager {
val apiService by lazy {
RetrofitFactory.instance.create(ApiService::class.java)
}
}
複製程式碼
interface ApiService {
@POST(API.LOGIN)
fun loginAsync(@Query("username") username: String,
@Query("password") password: String): Deferred<BaseResponse<LoginRsp>>
}
複製程式碼
以上就是登入的全過程。看到這裡,編寫一個簡單Login
功能需要新建四個類,有點麻煩。有沒有更便捷的方法的。那肯定!KtArmor
框架還有與之對應 KtArmor-MVP
外掛,幫助開發者快速生成對應模板程式碼(Activity
、Presenter
、Contract
、Model
)。
未完待續
這是KtArmor開篇的第一篇。大概講解了KtArmor基本用法。後續會詳細講解框架的使用、以及外掛的使用。至於KtArmor-MVVM
版目前還在測試階段。後續也會陸續更新。敬請期待吧!
著急的小夥伴可以直接檢視下文原始碼
~
最後
KtArmor
框架是一款小而美的框架,也是我個人經驗的積累, 總結。如有不妥, 望各位大佬指出。歡迎大家 pr交易
, 一起交流學習。
KtArmor-MVP 原始碼傳送門
Kotlin的魔能機甲——KtArmor外掛篇(二)
Kotlin的魔能機甲——KtArmor(三)
下次再見