diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 632955d..3e61b0b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ package="keijumt.todoapp"> { + return DependencyInjector.initialize(this) + } +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/MainActivity.kt b/app/src/main/java/keijumt/todoapp/MainActivity.kt index 291c380..82cf3bd 100644 --- a/app/src/main/java/keijumt/todoapp/MainActivity.kt +++ b/app/src/main/java/keijumt/todoapp/MainActivity.kt @@ -1,12 +1,20 @@ package keijumt.todoapp import android.os.Bundle -import android.support.v7.app.AppCompatActivity +import android.support.v4.app.Fragment +import dagger.android.AndroidInjector +import dagger.android.support.HasSupportFragmentInjector +import keijumt.todoapp.activity.BaseActivity +import keijumt.todoapp.di.Injectable -class MainActivity : AppCompatActivity() { +class MainActivity : BaseActivity(), HasSupportFragmentInjector, Injectable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } + + override fun supportFragmentInjector(): AndroidInjector { + return androidInjector + } } diff --git a/app/src/main/java/keijumt/todoapp/activity/BaseActivity.kt b/app/src/main/java/keijumt/todoapp/activity/BaseActivity.kt new file mode 100644 index 0000000..b66a967 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/activity/BaseActivity.kt @@ -0,0 +1,20 @@ +package keijumt.todoapp.activity + +import android.support.v4.app.Fragment +import android.support.v7.app.AppCompatActivity +import dagger.android.DispatchingAndroidInjector +import keijumt.todoapp.viewmodel.ViewModelFactory +import javax.inject.Inject + +/** + * Activityの基底クラス + * Created by matsumoto_k on 2018/03/06. + */ +abstract class BaseActivity : AppCompatActivity() { + + @Inject + lateinit var androidInjector: DispatchingAndroidInjector + + @Inject + lateinit var viewModelFactory: ViewModelFactory +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/ActivityModule.kt b/app/src/main/java/keijumt/todoapp/di/ActivityModule.kt new file mode 100644 index 0000000..6e2bf9d --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/ActivityModule.kt @@ -0,0 +1,15 @@ +package keijumt.todoapp.di + +import dagger.Module +import dagger.android.ContributesAndroidInjector +import keijumt.todoapp.MainActivity + +/** + * DIするActivity + */ +@Module +internal abstract class ActivityModule { + + @ContributesAndroidInjector + internal abstract fun contributeMainActivity(): MainActivity +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/AppAutomaticInjector.kt b/app/src/main/java/keijumt/todoapp/di/AppAutomaticInjector.kt new file mode 100644 index 0000000..44f895c --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/AppAutomaticInjector.kt @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package keijumt.todoapp.di + +import android.app.Activity +import android.app.Application +import android.os.Bundle +import android.support.v4.app.Fragment +import android.support.v4.app.FragmentActivity +import android.support.v4.app.FragmentManager +import dagger.android.AndroidInjection +import dagger.android.support.AndroidSupportInjection +import dagger.android.support.HasSupportFragmentInjector +import keijumt.todoapp.App + +/** + * Helper class to automatically inject fragments if they implement [Injectable]. + */ +object AppAutomaticInjector { + + fun init(app: App) { + DaggerAppComponent.builder().application(app).build().inject(app) + app.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { + override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { + handleActivity(activity) + } + + override fun onActivityStarted(activity: Activity) { + + } + + override fun onActivityResumed(activity: Activity) { + + } + + override fun onActivityPaused(activity: Activity) { + + } + + override fun onActivityStopped(activity: Activity) { + + } + + override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) { + + } + + override fun onActivityDestroyed(activity: Activity) { + + } + }) + } + + private fun handleActivity(activity: Activity) { + if (activity is HasSupportFragmentInjector) { + AndroidInjection.inject(activity) + } + (activity as? FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks( + object : FragmentManager.FragmentLifecycleCallbacks() { + override fun onFragmentCreated(fm: FragmentManager?, f: Fragment?, + savedInstanceState: Bundle?) { + if (f is Injectable) { + AndroidSupportInjection.inject(f) + } + } + }, true) + } +} diff --git a/app/src/main/java/keijumt/todoapp/di/AppComponent.kt b/app/src/main/java/keijumt/todoapp/di/AppComponent.kt new file mode 100644 index 0000000..454d532 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/AppComponent.kt @@ -0,0 +1,29 @@ +package keijumt.todoapp.di + +import android.app.Application +import dagger.BindsInstance +import dagger.Component +import dagger.android.AndroidInjector +import dagger.android.support.AndroidSupportInjectionModule +import keijumt.todoapp.App +import javax.inject.Singleton + +@Singleton +@Component(modules = arrayOf( + AndroidSupportInjectionModule::class, + AppModule::class, + ActivityModule::class, + ServiceModule::class) +) +interface AppComponent : AndroidInjector { + + @Component.Builder + interface Builder { + @BindsInstance + fun application(application: Application): Builder + + fun build(): AppComponent + } + + override fun inject(app: App) +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/AppModule.kt b/app/src/main/java/keijumt/todoapp/di/AppModule.kt new file mode 100644 index 0000000..2bf496c --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/AppModule.kt @@ -0,0 +1,7 @@ +package keijumt.todoapp.di + +import dagger.Module + +@Module(includes = arrayOf(ViewModelModule::class)) +class AppModule { +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/DependencyInjector.kt b/app/src/main/java/keijumt/todoapp/di/DependencyInjector.kt new file mode 100644 index 0000000..b43dbd9 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/DependencyInjector.kt @@ -0,0 +1,19 @@ +package keijumt.todoapp.di + +import android.app.Application + +object DependencyInjector { + + private lateinit var applicationComponent: AppComponent + + fun initialize(diApplication: Application): AppComponent { + applicationComponent = DaggerAppComponent.builder() + .application(diApplication) + .build() + return applicationComponent + } + + fun applicationComponent(): AppComponent { + return applicationComponent + } +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/FragmentBuildersModule.kt b/app/src/main/java/keijumt/todoapp/di/FragmentBuildersModule.kt new file mode 100644 index 0000000..174e813 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/FragmentBuildersModule.kt @@ -0,0 +1,10 @@ +package keijumt.todoapp.di + +import dagger.Module + +/** + * DIするFragment + */ +@Module +abstract class FragmentBuildersModule { +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/Injectable.kt b/app/src/main/java/keijumt/todoapp/di/Injectable.kt new file mode 100644 index 0000000..2ae5d38 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/Injectable.kt @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package keijumt.todoapp.di + +interface Injectable diff --git a/app/src/main/java/keijumt/todoapp/di/ServiceModule.kt b/app/src/main/java/keijumt/todoapp/di/ServiceModule.kt new file mode 100644 index 0000000..28a6584 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/ServiceModule.kt @@ -0,0 +1,10 @@ +package keijumt.todoapp.di + +import dagger.Module + +/** + * DIするService + */ +@Module +internal abstract class ServiceModule { +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/di/ViewModelKey.kt b/app/src/main/java/keijumt/todoapp/di/ViewModelKey.kt new file mode 100644 index 0000000..717e145 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/ViewModelKey.kt @@ -0,0 +1,12 @@ +package keijumt.todoapp.di + +import android.arch.lifecycle.ViewModel +import dagger.MapKey +import kotlin.reflect.KClass + +@MustBeDocumented +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +@MapKey +internal annotation class ViewModelKey(val value: KClass) + diff --git a/app/src/main/java/keijumt/todoapp/di/ViewModelModule.kt b/app/src/main/java/keijumt/todoapp/di/ViewModelModule.kt new file mode 100644 index 0000000..21e8bc7 --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/di/ViewModelModule.kt @@ -0,0 +1,24 @@ +package keijumt.todoapp.di + +import android.arch.lifecycle.ViewModel +import android.arch.lifecycle.ViewModelProvider +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import keijumt.todoapp.viewmodel.MainViewModel +import keijumt.todoapp.viewmodel.ViewModelFactory + +/** + * DIするViewModel + */ +@Module +internal abstract class ViewModelModule { + + @Binds + @IntoMap + @ViewModelKey(MainViewModel::class) + internal abstract fun bindMainViewModel(mainViewModel: MainViewModel): ViewModel + + @Binds + internal abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/viewmodel/MainViewModel.kt b/app/src/main/java/keijumt/todoapp/viewmodel/MainViewModel.kt new file mode 100644 index 0000000..2e2ac3c --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/viewmodel/MainViewModel.kt @@ -0,0 +1,11 @@ +package keijumt.todoapp.viewmodel + +import android.arch.lifecycle.LifecycleObserver +import android.arch.lifecycle.ViewModel +import javax.inject.Inject + +/** + * Created by matsumoto_k on 2018/03/06. + */ +class MainViewModel @Inject constructor() : ViewModel(), LifecycleObserver { +} \ No newline at end of file diff --git a/app/src/main/java/keijumt/todoapp/viewmodel/ViewModelFactory.kt b/app/src/main/java/keijumt/todoapp/viewmodel/ViewModelFactory.kt new file mode 100644 index 0000000..5eaeecb --- /dev/null +++ b/app/src/main/java/keijumt/todoapp/viewmodel/ViewModelFactory.kt @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package keijumt.todoapp.viewmodel + +import android.arch.lifecycle.ViewModel +import android.arch.lifecycle.ViewModelProvider +import javax.inject.Inject +import javax.inject.Provider + +class ViewModelFactory @Inject constructor(private val creators: Map, @JvmSuppressWildcards Provider>) + : ViewModelProvider.Factory { + + @Suppress("UNCHECKED_CAST") + override fun create(modelClass: Class): T { + var creator: Provider? = creators[modelClass] + if (creator == null) { + for ((key, value) in creators) { + if (modelClass.isAssignableFrom(key)) { + creator = value + break + } + } + } + if (creator == null) throw IllegalArgumentException("unknown model class " + modelClass) + try { + return creator.get() as T + } catch (e: Exception) { + throw RuntimeException(e) + } + } +} \ No newline at end of file