库房地址: github.com/lzyprime/an…

开发分支dev加入了compose, 图片库由 glide 换为 coil, DataStore替代SharedPreference。 一同剔除去LiveData, 用Flow替代。

本来想完全用compose结束UI结束。可是现在compose组件贫长生十万年瘠,与其他库的协作库也都没有安稳。部分场景下结束反倒费力。所以开两个分支:

  • dgit教程ev: compose 只做部分控件结束,主体仍保存传统gradle翻译库和其他方法。
  • dev_compose: view 层完全用okhttpclient compose 结束,包含路由导航。删去layout, navgation, menu等文件夹,删去compose 以外的依托。

hilt 或许 koin 做依托注入是贯穿大局的。所以得先会这个

android依托注入 官网文档

hilt 官网

koin 官网okhttp3运用详解

关于文档,仍是okhttp是干什么用的尽量看英文原版。原版文档本身有一定推延,而中文githup官网文档翻译又会推延一段。就导致文档里api或许已过时,内容丢掉等问okhttp面试题题。比如hilt在android官网的文档。中文版别仍是alpha版别的,@ViewModelInject接口现已丢掉等.

当然中文文档中介绍和原理部分仍是能够参阅,即便api改动了,这种东西一般也不会变。

共性:

无论是哪个库,原理都是相同gradle菜鸟教程的:

  1. Application, Activity, Fragment中开一个容器Container

  2. 所依托的实例从Container中获长沙商贸旅行工作技术学院得,并以单例存在于Containgithub敞开私库er

Android 手动依托注入文档

//example
classgithub直播渠道永久回家 MyApplication : Application() {
val appContainer = AppContainer()
..陈涉世家翻译及原文.
}
class LoginActivity: Activity(giti) {
private lateinitGit var loginViewModel: LoginViewModel
oveokhttpclientrride fun ogitlabnCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val appContaingithub敞开私库er = (application aGitHubs MyApplication).appContainer
loginViewModel = LoginViewModel(appContainegithub下载r.userRepository)
}
}

手动依托注入问题:

  • 必须自行办理 Contagithub永久回家地址iner,手动为依托项创立实例,根据生辰时是几点到几点命周期移除实giti
  • 样板代码
  • ViewModel依托注入,要靠ViewModelProvider.Factory才能够复用github官网Jetpack中的内容. 或许放进容器,自己保护Vieokhttp运用进程wModel生命周期。

依托注入有什么利益是陈词滥调。当然能够不必,通篇object, 直接就单例,处处能够运用。

依托注入优势,官网给的总结:

  • 重用类以及别离依托项:更简略换掉依托项的结束。由于控制回转,代码重用得以改善,并且类不再控制其依托项的创立方法,而是支持任何装备。
  • 易于重构:依托项成为 API Surface 的可验证部分,因此能够在创立目标时或编译时进行检查,而不是作为结束概况躲藏。
  • 易于检验:类不办理其依托项,因此在检验时,您可gradle下载以传入不同的结束以检验一切不同用例。

Hilt

Hilt做法是改动并拓展基类,比如继承自Application的,经过生成的Hilt_XXApplication,在里面结束okhttp原理容器保护。能够看生成的代码。

开容器

经过@HiltAndroidApp, @AndokhttpclientroidEntryPoint符号,生成对应基类,在基类里结束容器的保护逻辑长生十万年

@HiltAndroidApp
class UnsplashApplokhttp优点ication : Appgradle打包licatokhttp运用iongithub是干什么的()
@Androigradle菜鸟教程dEntryPoint
class MainActivity : AppCompatActivity()

@Inject 符号需求注入项

class UnsplashRepository @Inject construgradle插件ctoCSSr(private val sergithub中文官网网页vice: UnsplashService)
@Andgit指令roidEntryPoint
class MainActivity : AppCompgithub敞开私库atActivity() {
@Injectgithub中文社区 lateinit vagithubr service: XXService
...
}

注册实例获取办okhttp运用

创立 @Module,gradle打包 经过 @Provides@Binds 符号实例获取方法,并经过 @InstallIn 符号实例放在哪个容器里。

@Binds

ingradle教程terface XXSergithup官网vice { ... }
cgradle打包lass XXServiceImpl @Inject constructor(
...
) :git指令 XXService { ... }
@Module
@InstallIn(ActivityComponent::class)
abstract class XXModulgithub永久回家地址e {
@Binds
abstract fun bindAnalyticokhttpclientsService(
xxServiceImpl: XXServiceImpl
)gradle打包: XXService
}

@Provides

interface XXService {
...
companion objecgithub永久回家地址t : XXService {
...
}
}
@Mgithub是干什么的odule
@InstallIn(ActivityComponent::class)
object XXModule {
@Provides
fun provideXXService(): X陈涉世家翻译及原文XService = XXService
}

两种okhttp源码剖析方法都能够符号某个实例的获取方法。@InstallIn(ActivityComponent) 符号存放在Activity的容器Container中。参照表:

component 注入到 create at destroyed at
SingletonComponent Application Application#onCreate() Application#onDestroy()
ActivityRetainedComponegradle装置装备nt N/A Activity#onCreate() Activity#onDestroy()
ViewModelComponent ViewModel ViewModel creatgithub直播渠道永久回家ed ViewModel destroyed
ActivityComponent Activity Activity#onCreate() Activity#onDestroy()
FragmentComponent Fragment Fragment#onAttach() Fragment#onDestroy()
ViewComponent View View#super() Vgithub中文官网网页iew destgradleroyed
ViewWithFragmentComponent View annotated withGit @WithFragmentBindings View#super() View dGitHubestroyed
ServiceComponent Service Service#onCreate() Service#onDestroy()

除此之外,也能够经过符号作用域的方法,符号存放在哪个容器中,如:okhttp运用进程

@Singleton // 放入Application容器中,相当于大局github打不开单例
class UserRepository @Inject constructor(...gradle菜鸟教程)

对照表:

class compongithub是干什么的ent Scope
Application SingletonComponenGitt @Singleton
Activity ActivityRetainedComponent @ActivityRetainedScoped
ViewModel ViewModelComponent @ViewModelScoped
Activity ActiGitHubvityComponent @ActivitySgradle装置装备coped
Fragment FragmentComponent @FragmentScoped
View ViewComponent @ViewScoped
View anno陈涉世家翻译及原文tated with @WithFragmentBindingsgradle打包 ViewWokhttp运用ithFragmentComponent @ViewScopokhttpcliented
Service ServiceComponent @陈思思ServiceScoped

这些花里胡哨的终究影响的不过是实例的生计周期,以及单例规gradle装备划,如符号了Activity内,则每个Activity都会各自保护一份单例。以此类推

为实例供给多个获取方法

// 限定符
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class DebugService
@Qualifier
@Retention(AnnotationRetention.BINARYokhttp原理)
annotation class ReleaseService
// module
@Module
@InstallIn(ApplicationComponent::class)
object NetworkModule {
@DebugSegit教程rvice
@Provides
fun provideDebugService(): XXService = XXSerOKHttpvice(debug_url)
@ReleaseService
@Provides
fun provideReleaseService(): XXService = XXService(release_url)
}
// use
class UserRepository @Inject constructor(
@DebugSokhttp优点ervice service: XXService
)
// or
class Example {
@Release
@Inject lateinit var okHttpClient: OkHttpClient
}

预设限定符:@ApplicationContext@ActivityContext

cla陈思思ss Anagithub是干什么的lyticsAdapter @Inject constructor(
@Activ潮汕是哪个省的城市ityContgradle翻译ext private val context: Context,
privaokhttp运用te val service: Analokhttp3运用详解yticsService
) { ... }

ViewModel

运用@HiltViewModel符号,在Activity中仍然能够经过 by viewModels() 的方法获取到。

@HGitiltViewModel
class ExampleViewModel @Inject c仓鼠养殖八大忌讳onstructor(
private val savedStateHandle: SavedStateHandle,
prgradle是什么ivate val repository: ExampleRepository
) : ViewModel() {
...
}
@AndroidEntryPoint
class ExampleActivity : AppCompatActgithub敞开私库ivity() {
private val潮汕是哪个省的城市 exampleViewModel: ExampleViewModel by viewMgradle菜鸟教程odels()
...gradle和maven的差异
}

要了解怎样做到的,首要要知道by viewModel()怎样结束。完好的函数是要传ViewModel Factor陈涉世家翻译及原文y 获取方法的,缺省值为空,当什么都不穿时,会调用Activity#getDefaultViewModelProviderFactory。会创立个默许工厂。

Hilt结束的注入方法,便是改动并拓展基类。所以在生成的Activity基类里,ovegradle装备rride掉这个函数,先去Hilt中找,没有匹配的则回来gitlab默许行为。

这是KoinHilt明显差别之一。 Koin类似于把手动注入的进程封装一下,所以 bygit指令 viewModel()koin 库额定结束的一版,与原有同名,是两个不同函数。

Navigation

能够以导航图为单位同gitee享一个 ViewModel

val viewModel: ExampleViewModel by hiltNavGraphVgithub中文社区iewgithub中文社区ModCSSels(R.id.mgitlaby_graph)

gradle潮汕是哪个省的城市 plugin 生成代码

得益于Hilokhttp源码剖析t经过Gradle Plugin生成代CSS码, 否则我们就要:

@HiltAndroidApp(Application.class)
class FooApplication : Hilt_FooApplication
@AndroidEntryPoint(FragmentActivity.claokhttp优点ss)
class FooActivity : Hilt_FooActivity
...

Navigation SafeArgs 相同也是用 Gradle Plugin 生成代码的库,所以它并不gradle翻译dependencgradle下载ies{ implementation "xxx" } 而是在 plugins{ id "xxx" }

Koin

当了解了github是干什么的容器的概念,再来看Koin,或许其他依托注入库就很简略了解。Koin源码在github都有,能够自己扒。或许猜想一下结束,看库是长沙商贸旅行工作技术学院不是与自己相同。或许觉得库哪些内容结束不高雅欠好,有无更好的计划或写法。

开容器

Koin 经过 startKoin

class MainApplication : Applgithub下载ication() {
override fun onCreate(gradle和maven的差异) {
super.onCreate()
stgithub是干什么的artKoin {
// Koin Android logger
androidLogger()
//inject And仓鼠养殖八大忌讳roid context
androidContext(this@MainApplication)
// use modules
modules(myAppModules)
}
}
}

符号需求注入项

by inject()

class MySimpleActivity : AppComp长沙师范学院atActivity() {
vgithub永久回家地址al firstPresengitlabtergradle翻译: MySimplePresenter by inject()
}

get()

class MySimCSSpleActivity : AppCompatActivity() {
ovegithub敞开私库rride fun onCreate(savedInstanceState: Bgithup官网undl长沙市气候e?) {
super.onCreate(savedInstanceState)
val firstPresenter: MySimplePresgithub是干什么的enter = get()
}
}

注册实例获取方法

val appModule = module {
// single instance of HelloRepository
single<HelloRepository> { HgradleelloRepositoryImpl() }
// Simple Presenter Factory
factory { Mgithub中文社区ySimplgradle插件ePresenter(get()) }
}
startKoin {
...
// use modules
modules(myAppModules)
}

module 有具体文档。至于实例的生命周期和作用域,必定靠modulestartKoin注册方法保护。

ViewModel

class陈思思 MyViewModel(val repo : HelloRepository) : ViewModel() {...}
val appModgiteeule = module {
// single instance of HelloRepository
single<HelloRepository> { HelloRepositoryImpl() }
// MyViewModel ViewModel
viewModel { MyViewModel(get()) }
}

由于注入方法相当于手动保护容器,所以ViewModel也需求注册获取方法。

class My长沙商贸旅行工作技术学院ViewModelActivity : AppCompatActgradle是什么ivity() {
val myViewModel: MyViewModel by viewModel()
}

调用Koin库里的viewModel函数, 获取实例。

~:

其他具体内容可看文档和源码。两个库各有好坏,比较Koin, Hilt拓展基类,生成代码的方法或许更舒畅。