Keyword:Koin,Koin Compent
到Day20 使用Koin管理依赖注入显示在Android上 放在这边
KMMDay20
我们先在Android使用昨天建立的Koin物件吧.就跟正常的Koin使用流程一样,需要在Android的App启动时进行Koin的启动,因此我们在Android的根目录建立一个新的物件CafeApplication并且继承Application,让Koin可以在这里启动,有多第三方库也会要求使用时必须在Application预先载入.如果有用到其他部分的组件,请务必在Koin之後再开始启动流程.不然这块的物件就会超脱Koin的管理,这样就失去了依赖注入的特性了.
import android.app.Application
import android.content.Context
import com.officeyuli.kmmforit.initKoin
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module
class CafeApplication : Application() {
override fun onCreate() {
super.onCreate()
initKoin(
module {
single<Context> { this@CafeApplication }
viewModel { MainViewModel() }
}
)
}
}
在这里我们呼叫了昨天写好的一个funcion ,initKoin,回去看initKoin有要求提供一个appModule,这边就交由各平台实作.那Android这边有两个特别的物件建立或提供,第一个就是ApplicationContext,不管是使用DB或是SharedPreferences都需要这个,所以先交给Koin帮我们管理(当然在iOS就没有需要这个了),在几天後的DB使用教学就会用到了
另外一个就是ViewModel,在一般的Android App里面,使用ViewModel的时候需要提供生命周期的宿主,像是某一个Activity或是Fragment,但是我们藉由Koin提供的DSL,可以自动根据ViewModel所在的View层物件,来自动建立对应的ViewModel.是不是很方便呢.
这边有一点要特别注意,因为viewModel这个Term太多人使用了,在使用Koin的viewModel功能时,要注意不要使用到错误的import.所以我今天特别把import加了上去.
接下来要让Android系统知道启动的时候要呼叫这个Application,所以修改androidApp内的AndroidManifest.xml.在application的tag内加上指定的Application,也就是刚刚建立的CafeApplication.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.officeyuli.kmmforit.android">
<application
android:name=".CafeApplication"//加入这行来指定启动时使用的预设Application
android:allowBackup="false"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
...
>
</activity>
</application>
</manifest>
然後我们修改MainViewModel,让其实作KoinComponent这个interface.这是为了让Koin可以提供,我们不用做特别的动作.
然後根据我们昨天写的Module,现在Koin知道如何提供DataRepositoy的实体了,那麽我们可以使用by inject()方法,让Koin来代替我们完成物件的建立.现在MainViewModel不用知道这些物件怎麽建立的了.
class MainViewModel : ViewModel(), KoinComponent {
private val dataRepository: DataRepository by inject()
private val cafeList = MutableLiveData<List<CafeResponseItem>>()
val cafeListLiveData: LiveData<List<CafeResponseItem>> = Transformations.map(cafeList) { it }
fun fetchCafeData(city: String = "") {
viewModelScope.launch() {
val result = async { dataRepository.fetchCafesFromNetwork(city) }
cafeList.value = result.await()
}
}
}
同样的,Activity内的viewModel宣告,由於Koin已经自动帮我们建立好了ViewModel的建立过程,因此可以由Koin代为效劳.我们把里面的MainViewModel建立过程替换掉.
import org.koin.androidx.viewmodel.ext.android.viewModel
class MainActivity:AppCompatActivity() {
...
private val viewModel : MainViewModel by viewModel()
...
}
同样要注意viewModel不要用错了,要import的是koin的.
之前我们的ViewModel是可变数var,而在使用Koin提供後,会要求改变为不可变数val,这样就不会在使用流程中,再次的重新定义给viewModel变数了.这样物件的建立与销毁都由Koin来管理.
执行起来,跟原本的状态是一样的,但是MainActivity ,MainViewModel与DataRepository的耦合程度大大的降低了.
今天完成了Android的部分,我们明天会来做iOS的部分
<<: [Day10 ] NAT Slipstreaming
>>: JavaScript入门 Day20_function介绍3
文件 Physical Memory Model 翻译: SPARSEMEM ========= S...
今天来用 Cloudflare Workers 写个有趣的东西吧! 你的 IP 是不是 ? 很酷吧!...
今天挑战半小时写完一篇文章(被打,其实我写完程序了,把文章撰写出来就好噜。 https://jerr...
PWM-脉冲宽度调变 我相信很多人在使用Arduion的时候还是不清楚PWM到底在干嘛? PWM是一...
目前的内容中,一个变数在同一个时间只能储存一个资料,如果有多笔资料就需要有多个变数 如果要计算三个数...