Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android P : AppComponentFactory

omjoonkim
August 12, 2018

Android P : AppComponentFactory

Apply Dependency Injection with using AppComponentFactory

omjoonkim

August 12, 2018
Tweet

More Decks by omjoonkim

Other Decks in Programming

Transcript

  1. ӣߧળ - ࣗ೐౟ਝয ݃ীझ౟۽ 6thݭ౭ - അ ۨ੉פझ౟ উ٘۽੉٘ ѐߊ੗

    - জѐߊ ױ୓ MashUpױ੢ - Email : [email protected] - GitHub : @omjoonkim - Slack : @omjoonkim
  2. ੄ઓ ҙ҅ ࢸ੿੉ ஹ౵ੌदо ইצ प೯दী ੉ܖযઉ ݽٕٜр੄ Ѿ೤ب ܳ

    ծ୹ ࣻ ੓׮. ௏٘ ੤ࢎਊਸ ֫ৈࢲ ੘ࢿػ ݽٕਸ ৈ۞ Ҕীࢲ ࣗझ௏٘੄ ࣻ੿ হ੉ ࢎਊೡ ࣻ ੓׮. ݽ੄ ё୓١ਸ ੉ਊೠ ױਤ పझ౟੄ ಞ੄ࢿਸ ֫ৈળ׮. ҙब੄ ܻ࠙(separation of concern)ܳ ׳ࢿ ೡ ࣻ ੓׮.
  3. ੄ઓࢿ ઱ੑ(੄ઓ ҙ҅ ઱ੑ). ё୓ ژח ҳࢿ ਃࣗр੄ ੄ઓҙ҅ܳ ࣗझ௏٘۽

    ࢸ੿ ೞ૑ ঋҊ ৻ࠗ੄ ࢸ੿౵ੌ(ۄ੉࠳۞ܻ,೒ۖಬীࢲ ઁ ҕೞח ӝמ)ਸ ా೧ࢲ ઱ੑೞب۾ ೞח ٣੗ੋ ಁఢ
  4. ૓ੑ੢߷, ۞׬ழ࠳о ֫׮…. Annotation Processing ӝ߈੉ӝ ٸޙী ௏٘۝੉ ழ૑Ҋ ࠂ੟೧

    ૕ ࣻ۾ ஹ౵ੌ, ࠽٘ दр੉ טযդ׮... DIо ࣻ೯غח ߑध੉ ೧׼ ஹನք౟о ࢤࢿ ؼ ٸ ੗زਵ۽ ੉ܖয૑ח Ѫ੉ ইצ ੗न੉ ૒੽ ౠ੿ ݫࣗ ٘ܳ ഐ୹ೞৈ ੉ܖয૑ח ߑध੉׮.
  5. class ViewModelFactory( private val appModule: AppModule ) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T = when (modelClass) { MainViewModelImpl::class.java -> MainViewModelImpl(appModule.environment) as T else -> throw IllegalStateException() } }
  6. class ViewModelFactory( private val appModule: AppModule ) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T = when (modelClass) { MainViewModelImpl::class.java -> MainViewModelImpl(appModule.environment) as T else -> throw IllegalStateException() } }
  7. class ViewModelFactory( private val appModule: AppModule ) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T = when (modelClass) { MainViewModelImpl::class.java -> MainViewModelImpl(appModule.environment) as T else -> throw IllegalStateException() } }
  8. class AppModule(private val app: App) { val applicationContexxt get() =

    app.applicationContext private val gson by lazy { Gson() } private val loggingInterceptor by lazy { HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } } private val okHttpClient by lazy { OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .addInterceptor(loggingInterceptor) .build() } private val apiService: APIService by lazy { Retrofit.Builder() .client(okHttpClient) .baseUrl(APIService.EndPoint.baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(APIService::class.java) } private val apiClient: APIClientType by lazy { APIClient(apiService) } private val gitHubDataRepository: GitHubRepositoryType by lazy { GitHubDataRepository(apiClient) } val environment by lazy { Environment( gitHubDataRepository, gson ) } }
  9. class AppModule(private val app: App) { val applicationContexxt get() =

    app.applicationContext private val gson by lazy { Gson() } private val loggingInterceptor by lazy { HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } } private val okHttpClient by lazy { OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .addInterceptor(loggingInterceptor) .build() } private val apiService: APIService by lazy { Retrofit.Builder() .client(okHttpClient) .baseUrl(APIService.EndPoint.baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(APIService::class.java) } private val apiClient: APIClientType by lazy { APIClient(apiService) } private val gitHubDataRepository: GitHubRepositoryType by lazy { GitHubDataRepository(apiClient) } val environment by lazy { Environment( gitHubDataRepository, gson ) } } class AppModule(private val app: App)
  10. class AppModule(private val app: App) { val applicationContexxt get() =

    app.applicationContext private val gson by lazy { Gson() } private val loggingInterceptor by lazy { HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } } private val okHttpClient by lazy { OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .addInterceptor(loggingInterceptor) .build() } private val apiService: APIService by lazy { Retrofit.Builder() .client(okHttpClient) .baseUrl(APIService.EndPoint.baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(APIService::class.java) } private val apiClient: APIClientType by lazy { APIClient(apiService) } private val gitHubDataRepository: GitHubRepositoryType by lazy { GitHubDataRepository(apiClient) } val environment by lazy { Environment( gitHubDataRepository, gson ) } } private val gson by lazy { Gson() } private val loggingInterceptor by lazy { HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } } private val okHttpClient by lazy { OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .addInterceptor(loggingInterceptor) .build() } private val apiService: APIService by lazy { Retrofit.Builder() .client(okHttpClient) .baseUrl(APIService.EndPoint.baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(APIService::class.java) } private val apiClient: APIClientType by lazy { APIClient(apiService) }
  11. class AppModule(private val app: App) { val applicationContexxt get() =

    app.applicationContext private val gson by lazy { Gson() } private val loggingInterceptor by lazy { HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } } private val okHttpClient by lazy { OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .addInterceptor(loggingInterceptor) .build() } private val apiService: APIService by lazy { Retrofit.Builder() .client(okHttpClient) .baseUrl(APIService.EndPoint.baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(APIService::class.java) } private val apiClient: APIClientType by lazy { APIClient(apiService) } private val gitHubDataRepository: GitHubRepositoryType by lazy { GitHubDataRepository(apiClient) } val environment by lazy { Environment( gitHubDataRepository, gson ) } } private val gson by lazy { Gson() } private val loggingInterceptor by lazy { HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } } private val okHttpClient by lazy { OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .addInterceptor(loggingInterceptor) .build() } private val apiService: APIService by lazy { Retrofit.Builder() .client(okHttpClient) .baseUrl(APIService.EndPoint.baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(APIService::class.java) } private val apiClient: APIClientType by lazy { APIClient(apiService) } Daggerীࢲ provideೞח Ѫ җ ਬࢎ
  12. class AppModule(private val app: App) { val applicationContexxt get() =

    app.applicationContext private val gson by lazy { Gson() } private val loggingInterceptor by lazy { HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } } private val okHttpClient by lazy { OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .addInterceptor(loggingInterceptor) .build() } private val apiService: APIService by lazy { Retrofit.Builder() .client(okHttpClient) .baseUrl(APIService.EndPoint.baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(APIService::class.java) } private val apiClient: APIClientType by lazy { APIClient(apiService) } private val gitHubDataRepository: GitHubRepositoryType by lazy { GitHubDataRepository(apiClient) } val environment by lazy { Environment( gitHubDataRepository, gson ) } } val environment by lazy { Environment( gitHubDataRepository, gson ) }
  13. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } }
  14. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } class ComponentFactory : AppComponentFactory()
  15. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } private lateinit var appModule: AppModule private lateinit var viewModelFactory: ViewModelFactory
  16. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } override fun instantiateApplicationCompat( cl: ClassLoader, className: String ): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app }
  17. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } override fun instantiateApplicationCompat( cl: ClassLoader, className: String ): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app }
  18. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } override fun instantiateApplicationCompat( cl: ClassLoader, className: String ): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } public @NonNull Application instantiateApplicationCompat(@NonNull ClassLoader cl, @NonNull String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException { try { return (Application) cl.loadClass(className).getDeclaredConstructor().newInstance(); } catch (InvocationTargetException | NoSuchMethodException e) { throw new RuntimeException("Couldn't call constructor", e); } }
  19. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } override fun instantiateApplicationCompat( cl: ClassLoader, className: String ): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app }
  20. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } override fun instantiateActivityCompat( cl: ClassLoader, className: String, intent: Intent? ): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory) .get(MainViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity }
  21. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } override fun instantiateActivityCompat( cl: ClassLoader, className: String, intent: Intent? ): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory) .get(MainViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity }
  22. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } private fun <T : ViewModel> BaseActivity<T>.preBindViewModel( findViewModel: BaseActivity<T>.() -> T ) = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) }
  23. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } private fun <T : ViewModel> BaseActivity<T>.preBindViewModel( findViewModel: BaseActivity<T>.() -> T ) = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } ViewModelProviders.of(this, viewModelFactory) .get(MainViewModelImpl::class.java)
  24. class ComponentFactory : AppComponentFactory() { private lateinit var appModule: AppModule

    private lateinit var viewModelFactory: ViewModelFactory override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { val app = super.instantiateApplicationCompat(cl, className) as App appModule = AppModule(app) viewModelFactory = ViewModelFactory(appModule) return app } override fun instantiateActivityCompat(cl: ClassLoader, className: String, intent: Intent?): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) return if (activity is BaseActivity<*>) { return when (activity) { is MainActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(MainViewModelImpl::class.java) } is SearchActivity -> activity.preBindViewModel { ViewModelProviders.of(this, viewModelFactory).get(SearchViewModelImpl::class.java) } else -> throw IllegalArgumentException() } } else activity } private inline fun <reified VIEW_MODEL> BaseActivity<VIEW_MODEL>.preBindViewModel( crossinline findViewModel: BaseActivity<VIEW_MODEL>.() -> VIEW_MODEL ) where VIEW_MODEL : com.omjoonkim.app.mission.viewmodel.ViewModel = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) } } private fun <T : ViewModel> BaseActivity<T>.preBindViewModel( findViewModel: BaseActivity<T>.() -> T ) = apply { lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { bind(findViewModel()) } }) }
  25. override fun bind(viewModel: MainViewModel) { with(viewModel) { input.searchedUserName(intent.data.path.substring(1)) output.actionBarInit() .bind

    { actionbarInit(toolbar, title = it) } output.loading() .bind { if (it) loadingDialog.show() else loadingDialog.dismiss() } output.refreshListData() .bind { adapter.user = it.first adapter.repos = it.second adapter.notifyDataSetChanged() } output.error() .bind { if (it is Error) showToast(it.errorText) else showToast(UnExpected.errorText) finish() } } }
  26. END

  27. TMI

  28. instantiateActivity द੼ী Intent੄ чਸ ઑ੘ ೡ ࣻ ੓णפ׮. override fun

    instantiateActivityCompat( cl: ClassLoader, className: String, intent: Intent? ): Activity { val activity = super.instantiateActivityCompat(cl, className, intent) intent?.putExtra("Dummy", "A") } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) intent.getStringExtra("Dummy") == "A" }
  29. kotlinীࢲח Activity੄ ࢤࢿ੗ী ੋ੗ܳ ֍ਸ ࣻ ੓ ח ഒઙ௏٘ب….ٜ݅ ࣻ

    ੓ण… class MainActivity(viewModel: MainViewModel? = null) override fun instantiateActivityCompat( cl: ClassLoader, className: String, intent: Intent? ): Activity = appModule?.let { when (className) { MainActivity::class.java.name -> MainActivity(MainViewModel(it.enviorment)) else -> throw IllegalArgumentException() } } ?: throw IllegalStateException()
  30. CompatWrapped @Override public Activity instantiateActivity(ClassLoader cl, String className, Intent intent)

    throws InstantiationException, IllegalAccessException, ClassNotFoundException { return checkCompatWrapper(super.instantiateActivity(cl, className, intent)); } @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) public interface CompatWrapped { Object getWrapper(); } static <T> T checkCompatWrapper(T obj) { if (obj instanceof CompatWrapped) { T wrapper = (T) ((CompatWrapped) obj).getWrapper(); if (wrapper != null) { return wrapper; } } return obj; }
  31. CompatWrapped class MainActivity : AppCompatActivity(), CoreComponentFactory.CompatWrapped { override fun onCreate(savedInstanceState:

    Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } override fun getWrapper(): Any { return this } }
  32. хࢎ೤פ׮ github, slack: @omjoonkim facebook, kakao : @zkxns38 Rainist Android

    Engineer ӣߧળ ۨನ : https://github.com/omjoonkim/GitHubBrowserApp