为什么在 io() 线程中注入对象并进行 api 调用会减慢打开片段的速度?
Why Injecting objects and making api calls in io() thread slows opening the Fragment?
在 VacationFragment 的 onAttach() 中,我从 VacationViewModel -> VacationRepository 调用 featuredDays() ,
当我单击导航到 VacationFragment 的视图时,我注意到它会延迟打开,我正在等待几毫秒直到它打开 VacationFragment。
当我评论 vacationViewModel.featureDays(startDate,endDate)
它立即打开片段
class MainApplication : Application(), HasActivityInjector, HasSupportFragmentInjector {
override fun onCreate() {
super.onCreate()
appComponent = DaggerAppComponent.builder().androidModule(AndroidModule(this)).build()
appComponent.inject(this)
}
class VacationFragment : Fragment() {
override fun onAttach(context: Context?) {
AndroidSupportInjection.inject(this)
super.onAttach(context)
vacationViewModel = ViewModelProviders.of(activity, icaViewModelFactory).get(VacationViewModel::class.java)
vacationViewModel.featureDays(startDate,endDate)}
}
class VacationViewModel : ViewModel(), AppComponent.Injectable {
private val disposables: CompositeDisposable = CompositeDisposable()
@Inject
lateinit var vacationRepository: VacationRepository
val featuredFeaturedCalendar: MediatorLiveData<FeaturedCalendar> = MediatorLiveData()
fun featureDays(from: String, till: String) {
val disposable = vacationRepository
.featuredCalendar(from, till, KEY, ID)
.map { featuredCalendar ->
val holidays = arrayListOf<FeaturedCalendar.Holiday>()
featuredCalendar.holidays.forEach { holidayItem ->
val holiday = FeaturedCalendar.Holiday(format.parse(holidayItem.date), holidayItem.holiday)
holidays.add(holiday)
}
FeaturedCalendar(featuredCalendar.status, holidays)
}
.subscribeOn(Schedulers.io())
.observeOn(mainThread())
.subscribe(
{
featuredFeaturedCalendar.postValue(it)
},
{
throw IllegalStateException(it)
})
disposables.add(disposable)
}}
class VacationRepository(private val apiDaysSeResource: ApiDaysSeResource) {
fun featuredCalendar(from: String, till: String, key: String, id: String): Flowable<FeaturedCalendar> {
return apiDaysSeResource.days(from, till, key, id)//.toFlowable()
}
}
public interface ApiDaysSeResource {
Flowable<FeaturedCalendar> days(@Query("fran") String fran, @Query("till") String till, @Query("key") String key, @Query("id") String id);
}
对于不会阅读 OP 中完整 chat/comments 部分的任何人 - 问题在于 ApiDaysSeResource
class,它的创建需要很长时间才能完成.由于注入在 onAttach()
中同步发生,因此在启动时减速很明显。从 OP 所做的测试来看,减速似乎是 1.0 - 1.5 秒 ,这是很多。
如果您有空闲时间,我写了一篇很长的文章 post 关于这个问题以及当您无法访问需要很长时间才能完成的构造函数时如何异步注入单例。 Click here 阅读文章。
基本思想是注入 Observable<YourSlowThing>
而不是 YourSlowThing
- 这将允许您等待实例可用,但在启动时仍会获得非空依赖项。
在 VacationFragment 的 onAttach() 中,我从 VacationViewModel -> VacationRepository 调用 featuredDays() , 当我单击导航到 VacationFragment 的视图时,我注意到它会延迟打开,我正在等待几毫秒直到它打开 VacationFragment。 当我评论 vacationViewModel.featureDays(startDate,endDate) 它立即打开片段
class MainApplication : Application(), HasActivityInjector, HasSupportFragmentInjector {
override fun onCreate() {
super.onCreate()
appComponent = DaggerAppComponent.builder().androidModule(AndroidModule(this)).build()
appComponent.inject(this)
}
class VacationFragment : Fragment() {
override fun onAttach(context: Context?) {
AndroidSupportInjection.inject(this)
super.onAttach(context)
vacationViewModel = ViewModelProviders.of(activity, icaViewModelFactory).get(VacationViewModel::class.java)
vacationViewModel.featureDays(startDate,endDate)}
}
class VacationViewModel : ViewModel(), AppComponent.Injectable {
private val disposables: CompositeDisposable = CompositeDisposable()
@Inject
lateinit var vacationRepository: VacationRepository
val featuredFeaturedCalendar: MediatorLiveData<FeaturedCalendar> = MediatorLiveData()
fun featureDays(from: String, till: String) {
val disposable = vacationRepository
.featuredCalendar(from, till, KEY, ID)
.map { featuredCalendar ->
val holidays = arrayListOf<FeaturedCalendar.Holiday>()
featuredCalendar.holidays.forEach { holidayItem ->
val holiday = FeaturedCalendar.Holiday(format.parse(holidayItem.date), holidayItem.holiday)
holidays.add(holiday)
}
FeaturedCalendar(featuredCalendar.status, holidays)
}
.subscribeOn(Schedulers.io())
.observeOn(mainThread())
.subscribe(
{
featuredFeaturedCalendar.postValue(it)
},
{
throw IllegalStateException(it)
})
disposables.add(disposable)
}}
class VacationRepository(private val apiDaysSeResource: ApiDaysSeResource) {
fun featuredCalendar(from: String, till: String, key: String, id: String): Flowable<FeaturedCalendar> {
return apiDaysSeResource.days(from, till, key, id)//.toFlowable()
}
}
public interface ApiDaysSeResource {
Flowable<FeaturedCalendar> days(@Query("fran") String fran, @Query("till") String till, @Query("key") String key, @Query("id") String id);
}
对于不会阅读 OP 中完整 chat/comments 部分的任何人 - 问题在于 ApiDaysSeResource
class,它的创建需要很长时间才能完成.由于注入在 onAttach()
中同步发生,因此在启动时减速很明显。从 OP 所做的测试来看,减速似乎是 1.0 - 1.5 秒 ,这是很多。
如果您有空闲时间,我写了一篇很长的文章 post 关于这个问题以及当您无法访问需要很长时间才能完成的构造函数时如何异步注入单例。 Click here 阅读文章。
基本思想是注入 Observable<YourSlowThing>
而不是 YourSlowThing
- 这将允许您等待实例可用,但在启动时仍会获得非空依赖项。