์์ฑ์ผ: 2020.01.16
์ด ๊ธ์ Android Developer ๊ฐ์ด๋ ๋ด์ฉ์ ํ ๋๋ก ์์ฑ๋์์ต๋๋ค. ์์ ์ฝ๋๋ Kotlin๋ง ๊ฐ์ ธ์์ผ๋ฉฐ, Java ์ฝ๋๋ ์๋ฌธ์์ ํ์ธํ ์ ์์ต๋๋ค.
์ง์ ์์กด์ฑ ์ฃผ์ ํ๊ธฐ
Android์์ ๊ถ์ฅํ๋ ์ฑ ์ํคํ ์ฒ๋ ๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ์ด๋ฅผ ์ํด์๋ ์์ ํด๋์ค๋ค๋ก ๋์ฑ ์ชผ๊ฐ ํ, ์คํ์ ์ํด ๊ฐ ๋ํ๋์๋ฅผ ๋ชจ๋ ์ฐ๊ฒฐํด์ฃผ๋ ๊ณผ์ ์ด ํ์ํฉ๋๋ค.
MVVM ์ํคํ ์ฒ๋ Repository ํจํด์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, Anemic Repository๋ฅผ ๊ผญ ์ฝ์ด๋ณด์๊ธธ ์ถ์ฒํฉ๋๋ค!
ํด๋์ค ๊ฐ์ ์์กด ๊ด๊ณ๋ ๊ทธ๋ํ๋ก ๋ํ๋ผ ์ ์๊ณ , ๊ฐ ํด๋์ค๋ ์์ ์ด ์์กดํ๋ ํด๋์ค์ ์ฐ๊ฒฐ๋ฉ๋๋ค. ๋ชจ๋ ํด๋์ค์ ์์กด๊ด๊ณ๋ฅผ ๊ทธ๋ฆฌ๋ฉด ๊ณง ์ดํ๋ฆฌ์ผ์ด์ ๊ทธ๋ํ๊ฐ ๋ฉ๋๋ค. ๊ทธ๋ฆผ1์์ ์ดํ๋ฆฌ์ผ์ด์ ๊ทธ๋ํ์ ํํ๋ฅผ ๋ณผ ์ ์์ต๋๋ค. ํด๋์ค A(ViewModel)์ด ํด๋์ค B(Repository)์ ์์กดํ ๋, A์์ B๋ก ๊ฐ๋ ํ์ดํ๋ก ์์กด๊ด๊ณ๋ฅผ ํ์ํฉ๋๋ค.
DI๋ ์ด๋ฐ ์ฐ๊ฒฐ์ ํธ๋ฆฌํ๊ฒ ํด์ฃผ๊ณ , ํ ์คํธ ์ ๊ตฌํ์ฒด๋ฅผ ์ฝ๊ฒ ๋ฐ๊ฟ ์ ์๋๋ก ํด์ค๋๋ค. ํ Repository์ ์์กดํ๋ ViewModel์ ํ ์คํธํ๋ ๊ฒฝ์ฐ, Repository์ ๋ค๋ฅธ ๊ตฌํ์ฒด๋ฅผ ์ ๋ฌํ๋ฉด ๋ฉ๋๋ค.
์ง์ ์์กด์ฑ ์ฃผ์ ์ ๊ธฐ๋ณธ
์ด ํํธ์์๋ ์ค์ Android ์ฑ ํ๋ก์ฐ์ ์์กด์ฑ ์ฃผ์ ์ ์ด๋ป๊ฒ ์ ์ฉํ ์ ์๋์ง์ ๋ํด ์ค๋ช ํฉ๋๋ค. ์ฑ์ ์์กด์ฑ ์ฃผ์ ์ ์ฉ์ ์ด๋๋ถํฐ ์์ํด์ผ ํ ์ง๋ฅผ ๋ํ๋ด๊ณ , ๋์๊ฐ Dagger๊ฐ ์๋์ผ๋ก ์ด๋ค ๋ถ๋ถ๋ค์ ์์ฑํด์ฃผ๋์ง๋ฅผ ๋ํ๋ ๋๋ค. Dagger์ ๋ํ ์์ธํ ์ค๋ช ์ Part3. Dagger์์ ๋ณผ ์ ์์ต๋๋ค. (์ฐธ๊ณ : ๊ณต์ ์ฌ์ดํธ ๊ฐ์ด๋)
ํ ํ๋ก์ฐ๋ ํ ๊ธฐ๋ฅ์ ๋ํ ํ๋ฉด์ ๋ฌถ์์ด๋ผ๊ณ ์๊ฐํ์ธ์. ๋ก๊ทธ์ธ, ํ์๊ฐ์ ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ๋ค ๋ชจ๋ ํ๋ก์ฐ์ ์์๊ฐ ๋ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ธ Android ์ฑ์ ๋ก๊ทธ์ธ ํ๋ก์ฐ๋ฅผ ๊ทธ๋ ค๋ณด๋ฉด, LoginActivity๊ฐ LoginViewModel์ ์์กดํ๊ณ LoginViewModel์ UserRepository์ ์์กดํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ UserRepository๋ UserLocalDataSource์ UserRemoteDataSource์ ์์กดํ๋ฉฐ, UserRemoteDataSource๋ Retrofit ์๋น์ค์ ์์กดํฉ๋๋ค.
LoginActivity๊ฐ ํ๋ก์ฐ์ ์์์ ์ด๊ณ , ์ฌ์ฉ์๋ Activity๋ฅผ ํตํด ๊ธฐ๋ฅ์ ์ฌ์ฉํฉ๋๋ค. ์ฆ, LoginActivity๊ฐ ๋ชจ๋ ์์กด๊ด๊ณ์ LoginViewModel์ ์์ฑํด์ผ ํฉ๋๋ค.
์ด ํ๋ก์ฐ์ Repository์ DataSource๋ ์๋์ ๊ฐ์ด ๊ตฌํ๋์ด ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
class UserRepository(
private val localDataSource: UserLocalDataSource,
private val remoteDataSource: UserRemoteDataSource
) { ... }
class UserLocalDataSource { ... }
class UserRemoteDataSource(
private val loginService: LoginRetrofitService
) { ... }
LoginActivity์ ์ฝ๋์ ๋๋ค.
class LoginActivity: Activity() {
private lateinit var loginViewModel: LoginViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// LoginViewModel์ ์์กด๊ด๊ณ๋ฅผ ๋ง์กฑ์ํค๊ธฐ ์ํด์๋
// ์ฌ๊ท์ ์ผ๋ก ๋ชจ๋ ๋ํ๋์๊ฐ ํ์ํฉ๋๋ค.
// ๋จผ์ UserRemoteDataSource์ ๋ํ๋์์ธ retrofit์ ์์ฑํฉ๋๋ค.
val retrofit = Retrofit.Builder()
.baseUrl("https://example.com")
.build()
.create(LoginService::class.java)
// ๋ค์์ผ๋ก๋ UserRepository๋ฅผ ์ํ ๋ํ๋์๋ฅผ ์์ฑํฉ๋๋ค.
val remoteDataSource = UserRemoteDataSource(retrofit)
val localDataSource = UserLocalDataSource()
// ์ด์ LoginViewModel์์ ํ์ํ UserRepository ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
val userRepository = UserRepository(localDataSource, remoteDataSource)
// ๋๋์ด LoginViewModel ์ธ์คํด์ค ์์ฑ!
loginViewModel = LoginViewModel(userRepository)
}
}
์ด ๋ฐฉ๋ฒ์ผ๋ก๋ ์๋ ์ด์๊ฐ ์๊ธธ ์ ์์ต๋๋ค.
- ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๊ฐ ๋๋ฌด ๋ง์ต๋๋ค. ๋ค๋ฅธ ์ฝ๋์์ LoginViewModel ์ธ์คํด์ค๋ฅผ ๋ ์์ฑํด์ผ ํ๋ค๋ฉด, ์ฝ๋ ์ค๋ณต์ด ๋ฐ์ํฉ๋๋ค.
- ์์กด ๊ด๊ณ๊ฐ ๋ฐ๋์ ์์๋๋ก ์ ์๋์ด์ผ ํฉ๋๋ค. LoginViewModel ์์ฑ ์ ์ LoginRepository๋ฅผ ๋จผ์ ์์ฑํด์ผ๋ง ํฉ๋๋ค.
- ๊ฐ์ฒด ์ฌ์ฌ์ฉ์ด ์ด๋ ต์ต๋๋ค. UserRepository๋ฅผ ์ฌ๋ฌ ๊ธฐ๋ฅ์์ ์ฌ์ฌ์ฉํ๋ ค๋ฉด ์ฑ๊ธํค ํจํด์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ํ์ง๋ง ์ฑ๊ธํค ํจํด์ ํ ์คํธ์ ๋ชจ๋ ํ ์คํธ ์ผ์ด์ค๊ฐ ๋์ผํ ์ฑ๊ธํค ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ ํ ์คํธ๊ฐ ๋ ์ด๋ ค์์ง๋๋ค.
ํ๋์ ์ปจํ ์ด๋๋ก ์์กด ๊ด๊ณ ๊ด๋ฆฌํ๊ธฐ
๊ฐ์ฒด ์ฌ์ฌ์ฉ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, ๋ํ๋์ ์ปจํ ์ด๋๋ฅผ ์์ฑํฉ๋๋ค. ์ด ์ปจํ ์ด๋๋ฅผ ํตํด ํ์ํ ์์กด ๊ด๊ณ๋ฅผ ์ป์ต๋๋ค. ์ปจํ ์ด๋๋ฅผ ํตํด ์ป๋ ์ธ์คํด์ค๋ ๋ชจ๋ public ์ ๋๋ค. ์๋ฅผ ๋ค์ด, UserRepository ์ธ์คํด์ค๋ง ํ์ํ๋ค๋ฉด UserRepository ์ธ์ ๋๋จธ์ง ๋ํ๋์๋ private์ผ๋ก ํด๋จ๋ค๊ฐ ํ์ํ ๋ public์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
// Container of objects shared across the whole app
class AppContainer {
// ์ปจํ
์ด๋ ์ธ๋ถ์ userRepository๋ฅผ ๊ณต๊ฐํ๊ธฐ ์ํด ๋จผ์ ํ์ํ ๋ํ๋์๋ฅผ ์์ฑ
private val retrofit = Retrofit.Builder()
.baseUrl("https://example.com")
.build()
.create(LoginService::class.java)
private val remoteDataSource = UserRemoteDataSource(retrofit)
private val localDataSource = UserLocalDataSource()
// userRepository ๋ public
val userRepository = UserRepository(localDataSource, remoteDataSource)
}
์ด๋ฐ ๋ํ๋์๋ค์ ์ดํ๋ฆฌ์ผ์ด์ ๋ด์์ ์ ์ฒด์ ์ผ๋ก ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์, ๋ชจ๋ Activity๊ฐ ์ ๊ทผํ ์ ์๋ ๊ณตํต ๊ณต๊ฐ-Application ํด๋์ค-์ ์์ด์ผ ํฉ๋๋ค. ๋ฐ๋ผ์ AppContainer ์ธ์คํด์ค๋ฅผ ๊ฐ์ง๊ณ ์๋ ์ปค์คํ Application ํด๋์ค๋ฅผ ๋ง๋ญ๋๋ค.
class MyApplication : Application() {
val appContainer = AppContainer()
}
AppContainer๋ ์ฑ๊ธํค ํด๋์ค๊ฐ ์๋๊ณ , Application ํด๋์ค์ ์ ์ฅ๋ ์ธ์คํด์ค๋ฅผ ์ฑ ๋ด๋ถ์์ ๊ณต์ ํฉ๋๋ค. Kotlin์์๋ AppContainer๊ฐ object๊ฐ ์๋๋ฉฐ, Java์์๋ Singleton.getInstance() ์ฒ๋ผ ์ ๊ทผํ๋ ์ฑ๊ธํค ํด๋์ค๊ฐ ์๋๋๋ค.
์ด์ Application์์ AppContainer ์ธ์คํด์ค๋ฅผ ์ป์ ์ ์๊ณ , UserRepository ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
class LoginActivity: Activity() {
private lateinit var loginViewModel: LoginViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Application์ ์๋ AppContainer๋ก๋ถํฐ UserRepository ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
val appContainer = (application as MyApplication).appContainer
loginViewModel = LoginViewModel(appContainer.userRepository)
}
}
UserRepository๋ฅผ ์ฑ๊ธํค์ผ๋ก ๋ง๋ค์ง ์๊ณ , ๋ชจ๋ Activity์์ AppContainer ์ธ์คํด์ค์ ์์ฑ๋ UserRepository ์ธ์คํด์ค ํ๋๋ฅผ ๊ณต์ ํฉ๋๋ค.
LoginViewModel์ด ๋ ๋ง์ ๊ณณ์์ ํ์ํ๋ค๋ฉด, LoginViewModel์ ์์ฑํ๋ ์ฝ๋๋ฅผ ํ ๊ณณ์ ๋ชจ์ ์ ์์ต๋๋ค. ์์ฑ ์ฝ๋๋ฅผ ์ปจํ ์ด๋์ ์ฎ๊ธฐ๋ฉด ๋ฉ๋๋ค. LoginViewModelFactory์ ์์ ์ฝ๋์ ๋๋ค:
// Definition of a Factory interface with a function to create objects of a type
interface Factory {
fun create(): T
}
// Factory for LoginViewModel.
class LoginViewModelFactory(private val userRepository: UserRepository) : Factory {
override fun create(): LoginViewModel {
return LoginViewModel(userRepository)
}
}
AppContainer์ LoginViewModelFactory๋ฅผ ๋๊ณ , LoginActivity์์ LoginViewModelFactory๋ฅผ ์ฌ์ฉํ๋๋ก ํฉ๋๋ค:
// AppContainer can now provide instances of LoginViewModel with LoginViewModelFactory
class AppContainer {
...
val userRepository = UserRepository(localDataSource, remoteDataSource)
val loginViewModelFactory = LoginViewModelFactory(userRepository)
}
class LoginActivity: Activity() {
private lateinit var loginViewModel: LoginViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Gets LoginViewModelFactory from the application instance of AppContainer
// to create a new LoginViewModel instance
val appContainer = (application as MyApplication).appContainer
loginViewModel = appContainer.loginViewModelFactory.create()
}
}
์ด ๋ฐฉ๋ฒ์ด ์์์ ์ค๋ช ํ ๊ฒ๋ณด๋ค ๋ซ์ง๋ง, ์ฌ์ ํ ๋ช ๊ฐ์ง ๋ฌธ์ ์ ์ด ์์ต๋๋ค:
- AppContainer๋ฅผ ์ง์ ๊ด๋ฆฌํด์ผ ํ๊ณ , ๋ชจ๋ ์์กด ๊ด๊ณ์ ํด๋นํ๋ ์ธ์คํด์ค ์์ฑ ์ฝ๋๋ฅผ ์ง์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
- ์ฌ์ ํ ๋ง์ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๊ฐ ์กด์ฌํฉ๋๋ค. ๊ฐ์ฒด ์ฌ์ฌ์ฉ์ด ํ์ํ๋๋์ ๋ฐ๋ผ Factory๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ ์จ์ค์ผ ํฉ๋๋ค.
์ดํ๋ฆฌ์ผ์ด์ ํ๋ก์ฐ ๊ด์ ์์ ์์กด ๊ด๊ณ ๊ด๋ฆฌํ๊ธฐ
ํ๋ก์ ํธ์ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋ ์๋ก AppContainer๋ ๋ณต์กํด์ง๋๋ค. ์ฑ์ด ์ปค์ง๋ฉด ๋ค๋ฅธ ๊ธฐ๋ฅ ํ๋ก์ฐ๊ฐ ์๊ธธ ์ ์๊ณ , ๊ทธ ๊ฒฝ์ฐ ์๋์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
- ์ด๋ค ๊ฐ์ฒด๋ ํ๋ก์ฐ์ scope์์๋ง ์ ํจํ๊ฒ ๋ง๋ค ํ์๊ฐ ์๊น๋๋ค. ์๋ฅผ ๋ค์ด (๋ก๊ทธ์ธ ํ๋ก์ฐ์์๋ง ์ฐ์ด๋ username๊ณผ password๋ฅผ ํฌํจํ๋) LoginUserData๋ฅผ ์์ฑํ์ ๋, ์ด์ ๋ก๊ทธ์ธ ํ๋ก์ฐ์ ๋ฐ์ดํฐ๊ฐ ๊ณ์ ์ ์ง๋์ง ์์์ผ ํฉ๋๋ค. ๋งค๋ฒ ์๋ก์ด ํ๋ก์ฐ๋ง๋ค ์๋ก์ด ์ธ์คํด์ค๊ฐ ํ์ํฉ๋๋ค. ํด๊ฒฐ์ ์ํด AppContainer ์์ ๋ค์ ์์ ์ฝ๋์์ ๋ณผ ์ ์๋ FlowContainer๋ฅผ ๋ง๋ญ๋๋ค.
- ์ดํ๋ฆฌ์ผ์ด์ ํ๋ก์ฐ๋ฅผ ์ต์ ํํ๊ธฐ๋ ์ด๋ ต์ต๋๋ค. ํ๋ก์ฐ๋ฅผ ๋ณด๊ณ ํ์์๋ ์ธ์คํด์ค๋ฅผ ์ฐพ์ ์ญ์ ํด์ผ ํฉ๋๋ค.
ํ Activity (LoginActivity)์ Fragment๋ค(LoginUsernameFragment, LoginPasswordFragment)๋ก ๊ตฌ์ฑ๋ ๋ก๊ทธ์ธ ํ๋ก์ฐ๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค. ํ๋ฉด์ ์๊ตฌ์ฌํญ์ ์๋์ ๊ฐ์ต๋๋ค:
- ๋ก๊ทธ์ธ ํ๋ก์ฐ๊ฐ ๋๋๊ธฐ ์ ์๋ ๊ฐ์ LoginUserData ์ธ์คํด์ค์ ์ ๊ทผ
- ํ๋ก์ฐ๊ฐ ๋ค์ ์์๋๋ฉด LoginUserData ์ธ์คํด์ค๋ฅผ ์๋ก ์์ฑ
๋ก๊ทธ์ธ ํ๋ก์ฐ ์ปจํ ์ด๋๋ฅผ ๋ง๋ค์ด ํด๊ฒฐํ ์ ์์ต๋๋ค. ์ด ์ปจํ ์ด๋๋ ๋ก๊ทธ์ธ ํ๋ก์ฐ๊ฐ ์์๋๋ฉด ์์ฑ๋๊ณ , ํ๋ก์ฐ๊ฐ ๋๋๋ฉด ๋ฉ๋ชจ๋ฆฌ์์ ์ง์์ง๋๋ค.
์์ ์ฝ๋์ LoginContainer๋ฅผ ์ถ๊ฐํด๋ด ์๋ค. ์ฌ๋ฌ LoginContainer๊ฐ ํ์ํ ์ ์์ผ๋, ์ฑ๊ธํค์ผ๋ก ๋ง๋ค์ง ์๊ณ AppContainer์ ์์กด ๊ด๊ณ์ธ ํด๋์ค๋ก ์ถ๊ฐํฉ๋๋ค.
class LoginContainer(val userRepository: UserRepository) {
val loginData = LoginUserData()
val loginViewModelFactory = LoginViewModelFactory(userRepository)
}
// AppContainer contains LoginContainer now
class AppContainer {
...
val userRepository = UserRepository(localDataSource, remoteDataSource)
// LoginContainer will be null when the user is NOT in the login flow
var loginContainer: LoginContainer? = null
}
ํน์ ํ๋ก์ฐ์ ํ์ ๋ ์ปจํ ์ด๋๋ ์ธ์คํด์ค๋ฅผ ์ธ์ ์์ฑํ๊ณ ์ ๊ฑฐํ ๊ฑด์ง์ ๋ํ ์ ์๊ฐ ํ์ํฉ๋๋ค. ๋ก๊ทธ์ธ ํ๋ก์ฐ๋ Activity (LoginActivity)์ ํฌํจ๋๊ธฐ ๋๋ฌธ์, Activity๊ฐ ์ปจํ ์ด๋์ ๋ผ์ดํ์ฌ์ดํด์ ๊ด๋ฆฌํ๋ ์ฃผ์ฒด๊ฐ ๋ ์ ์์ต๋๋ค. LoginActivity onCreate() ์์ ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ , onDestroy() ์์ ์ ์ ๊ฑฐํฉ๋๋ค.
class LoginActivity: Activity() {
private lateinit var loginViewModel: LoginViewModel
private lateinit var loginData: LoginUserData
private lateinit var appContainer: AppContainer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
appContainer = (application as MyApplication).appContainer
// Login flow has started. Populate loginContainer in AppContainer
appContainer.loginContainer = LoginContainer(appContainer.userRepository)
loginViewModel = appContainer.loginContainer.loginViewModelFactory.create()
loginData = appContainer.loginContainer.loginData
}
override fun onDestroy() {
// Login flow is finishing
// Removing the instance of loginContainer in the AppContainer
appContainer.loginContainer = null
super.onDestroy()
}
}
๋ก๊ทธ์ธ ๊ด๋ จ Fragment๋ค๋ AppContainer์ LoginContainer๋ฅผ ํตํด ๋์ผํ LoginUserData๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
DI๋ ํ์ฅ ๊ฐ๋ฅํ๊ณ ํ ์คํธ ๊ฐ๋ฅํ Android ์ฑ์ ๋ง๋๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ์ปจํ ์ด๋๋ฅผ ํตํด ํด๋์ค ์ธ์คํด์ค๋ฅผ ๊ณต์ ํ๊ณ , ์ธ์คํด์ค ์์ฑ ์ฝ๋๋ฅผ ์ปจํ ์ด๋์ ๋ชจ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ฑ์ด ์ ์ ์ปค์ง์๋ก ๋ง์ ์์ Factory ์ฝ๋์ ๊ฐ์ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๊ฐ ์๊ธฐ๊ธฐ ์์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ ์๋ฌ๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ์ต๋๋ค. ์ปจํ ์ด๋์ scope์ด๋ ๋ผ์ดํ์ฌ์ดํด๊น์ง ์ง์ ๊ด๋ฆฌํด์ผํ๊ณ , ๋ฉ๋ชจ๋ฆฌ ํด์ ๋ฅผ ์ํด ๋์ด์ ์ฌ์ฉํ์ง ์๋ ์ปจํ ์ด๋ ์ ๊ฑฐ๋ ํด์ผ ํฉ๋๋ค. ์ด๋ฐ ๊ด๋ฆฌ๋ฅผ ์๋ชป ํ๊ฒ๋๋ฉด ์ ์ฌ์ ์ธ ๋ฒ๊ทธ๋ ๋ฉ๋ชจ๋ฆฌ๋ฆญ์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
๋ค์ ํํธ์์๋ ์ด๋ฐ ๊ณผ์ ๋ค์ Dagger๋ฅผ ์ด์ฉํด ์ด๋ป๊ฒ ์๋ํํ๊ณ , ์ฌ๊ธฐ์ ์ง์ ์ผ๋ ์ฝ๋๋ค์ ์ด๋ป๊ฒ ์์ฑํ๋์ง ์์๋ณด๊ฒ ์ต๋๋ค!
'๊ฐ๋ฐ > Android' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android] java.lang.UnsupportedOperationException: This session doesn't support queue management operations (0) | 2021.04.09 |
---|---|
Android 10 ๋ณ๊ฒฝ ์ฌํญ : Scoped Storage (0) | 2021.04.09 |
[Android] Dependency Injection Part 1. Overview (0) | 2021.04.08 |
Android ๊ฐ๋ฐ์๋ฅผ ์ํ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ Part 2 (0) | 2021.04.08 |
Android ๊ฐ๋ฐ์๋ฅผ ์ํ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ Part 1 (0) | 2021.04.08 |