Container
Prepare main container and sub containers. This container contains all dependencies.
This idea is from Google Android Manual dependency injection page
Sample
Prepare AppContainer to use components for entire app.
This class contains
- data sources
- Repository with data sources
- Singleton object
- Model factory
- Sub container (to manage lifecycle)
AppContainer.kt
This is main container which has all injections
class AppContainer { val retrofit = Retrofit.Builder() .baseUrl("https://dj110.it") .build() .create(DataRetrofitService::class.java) val remoteDataSource = DataRemoteDataSource(retrofit) val localDataSource = DataLocalDataSource() val dataRepository = DataRepository(localDataSource, remoteDataSource) // Create model from factory val dataViewModelFactory = DataViewModelFactory(dataRepository) // Consider lifecycle (only create and use when to use) var dataContainer : DataContainer? = null }
DataContainer
Data Container is sub component (container) to use other Activity, Fragment. Recommend to create one container for Activity.
class DataContainer(val dataRepository: DataRepository) { val dataData = Data("") val dataModelFactory = DataViewModelFactory(dataRepository) }
ModelFactory.kt
This is ViewModel (not Android Architect Component one), factory interface
interface ModelFactory<T> { fun create() : T }
Implement this interface to support returning ViewModel
DataViewModelFactory.kt
This is ViewModel Factory class.
class DataViewModelFactory(private val dataRepository: DataRepository) : ModelFactory<DataViewModel> { override fun create(): DataViewModel { return DataViewModel(dataRepository) } }
DataViewModel.kt
This is ViewModel class. To manipulate UI data etc…
The key of MVVM
class DataViewModel (private val dataRepository: DataRepository) { }
DataRepository.kt
Repository is data manipulation class (retrieve data mainly)
class DataRepository ( private val localDataSource: DataLocalDataSource, private val remoteDataSource: DataRemoteDataSource ) { } class DataLocalDataSource() {} class DataRemoteDataSource(private val dataService: DataRetrofitService) {}
DataRetrofitService.kt
For retrofit. More details, please check other my blog (Android kotlin Retrofit).
interface DataRetrofitService { @GET("/data") fun getData() : Call<Data> }
Data.kt
It’s just model data class
data class Data(val name: String)
MyApplication.kt
This is override application class. This class creates container to manage this as everything.
class MyApplication : Application() { val appContainer = AppContainer() }
Of course, we need to register this in AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.daiji110.disample1"> <application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Let’s use ViewModel from 2 Activity
MainActivity.kt
class MainActivity : AppCompatActivity() { private lateinit var dataViewModel : DataViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // App Container val appContainer = (application as MyApplication).appContainer dataViewModel = DataViewModel(appContainer.dataRepository) } }
DataActivity.kt
class DataActivity : AppCompatActivity() { // View Model private lateinit var dataViewModel: DataViewModel // Data private lateinit var dataData: Data // Container (Application level) private lateinit var appContainer: AppContainer override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // LocalContainer in AppContainer // LocalContainer has : ViewModel factory and Data(model) appContainer = (application as MyApplication).appContainer // Create this activity level container dataViewModel = appContainer.dataContainer?.dataModelFactory!!.create() dataData = appContainer.dataContainer?.dataData!! } override fun onDestroy() { appContainer.dataContainer = null super.onDestroy() } }
See. DataContainer is destroyed when calling onDestroy().
コメント