學習了Kotlin有一段時間了, 每次寫項目/Demo
的時候, 老是用到網絡請求
、MVP
、MVVM
、經常使用工具類
、通用自定義View
, 索性把這些整合到一塊兒, 搭成一個Android的腳手架——KtArmor
.java
KtArmor
寓意着 爲Android 賦予戰鬥裝甲
, 方便開發者快速進行Android 開發。節約開發者開發時間。爲了知足開發者需求, 我整合了兩個分支, 分別對應着 MVP
, MVVM
.git
MVP
+ Kotlin
Retrofit
+ Okhttp
+ Coroutine
+ RxJava
BaseActivity
、BaseFragment
、ToolbarActivity
封裝MvpActivity
、MvpFragment
、BasePresenter
、BaseModel
封裝BaseOkHttpClient
、BaseRetrofit
、RetrofitFactory
PlaceHolderView(佔位佈局)
, LoadingView(加載框)
SharedPreferences
、StartActivity
、Log
、Toast
(不重複顯示))等Activity
、Presenter
、Contract
、Model
)生成插件MVVM
+ Androidx
+ Kotlin
+ LiveData
+ ViewModel
Coroutines
+ Retrofit
+ Okhttp
先在 build.gradle(Project:XXXX) 的 repositories 添加:github
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
複製代碼
而後在 build.gradle(Module:app) 的 dependencies 添加:api
implementation 'com.github.hyzhan43:KtArmor:mvp-1.0.4' // 根據github 引入最新版本便可
複製代碼
在Application 中初始化KtArmor
框架。新建一個application 類, 如 BaseApplication, 在 BaseApplication 中, 調用KtArmor的 init
方法, 進行初始化, 參數以下:bash
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
項目了。而後就能夠愉快編寫本身的業務代碼了(●'◡'●)架構
咱們先從簡單登陸流程來熟悉一下KtArmor。首先編寫 LoginContract, 代碼以下:app
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)
}
}
複製代碼
而後新建一個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("登錄成功!")
}
}
複製代碼
這裏 activity_login 裏面是簡單的 TextInputEditText,調用presenter, 發起登陸請求。傳遞帳號和密碼。其中 str() 爲 TextView 擴展方法。maven
str()
爲擴展方法// 獲取text內容
fun TextView.str(): String {
return this.text.toString()
}
複製代碼
而後咱們再看看對應 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 真正發起網絡請求操做。
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交易
, 一塊兒交流學習。
下次再見