Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HW-7 Koin 적용 #580

Merged
merged 11 commits into from
Apr 16, 2020
13 changes: 8 additions & 5 deletions 2003/mtjin/AndroidArchitectureStudy/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ dependencies {
//recyclerview
implementation 'androidx.recyclerview:recyclerview:1.1.0'
//retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:retrofit:2.7.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
//glide
implementation 'com.github.bumptech.glide:glide:4.11.0'
Expand All @@ -57,16 +57,19 @@ dependencies {
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
// Room
implementation "androidx.room:room-runtime:2.2.4"
testImplementation "androidx.room:room-testing:2.2.4"
kapt "androidx.room:room-compiler:2.2.4"
implementation 'androidx.room:room-ktx:2.2.4'
implementation "androidx.room:room-runtime:2.2.5"
testImplementation "androidx.room:room-testing:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
implementation 'androidx.room:room-ktx:2.2.5'
//coroutine lifecycle
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-alpha01"
//ktx extensions
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.fragment:fragment-ktx:1.2.4'
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"

// koin
implementation 'org.koin:koin-androidx-viewmodel:2.1.5'


}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
android:name=".di.KoinApplication"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:name=".utils.MyApplication"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".ui.login.LoginActivity"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,5 @@
package com.mtjin.androidarchitecturestudy.api

import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.IOException

object ApiClient {
private const val BASE_URL = "https://openapi.naver.com/"
fun getApiClient(): Retrofit {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(provideOkHttpClient(AppInterceptor()))
.addConverterFactory(GsonConverterFactory.create())
.build()
}

private fun provideOkHttpClient(
interceptor: AppInterceptor
): OkHttpClient = OkHttpClient.Builder()
.run {
addInterceptor(interceptor)
build()
}

class AppInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain)
: Response = with(chain) {
val newRequest = request().newBuilder()
.addHeader("X-Naver-Client-Id", "33chRuAiqlSn5hn8tIme")
.addHeader("X-Naver-Client-Secret", "fyfwt9PCUN")
.build()

proceed(newRequest)
}
}
const val BASE_URL = "https://openapi.naver.com/"
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class MovieRepositoryImpl(
fail(it)
}
)
}else{
} else {
fail(Throwable("네트워크가 연결이 되어있지 않습니다."))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,4 @@ import com.mtjin.androidarchitecturestudy.data.search.Movie
@Database(entities = [Movie::class], version = 1, exportSchema = false)
abstract class MovieDatabase : RoomDatabase() {
abstract fun movieDao(): MovieDao

companion object {

private var INSTANCE: MovieDatabase? = null

fun getInstance(context: Context): MovieDatabase {
synchronized(this) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
MovieDatabase::class.java, "Movie.db"
)
.allowMainThreadQueries()
.build()
}
return INSTANCE!!
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.mtjin.androidarchitecturestudy.di

import android.app.Application
import com.mtjin.androidarchitecturestudy.BuildConfig
import com.mtjin.androidarchitecturestudy.module.*
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
import org.koin.core.logger.Level

class KoinApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
if (BuildConfig.DEBUG) androidLogger()
else androidLogger(Level.NONE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{} 추가해주세요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

170728d
수정했습니다.

androidContext(this@KoinApplication)
modules(
repositoryModule,
localDataModule,
remoteDataModule,
networkModule,
viewModelModule,
apiModule
)

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.mtjin.androidarchitecturestudy.module

import com.mtjin.androidarchitecturestudy.api.ApiClient
import com.mtjin.androidarchitecturestudy.api.ApiInterface
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import org.koin.core.module.Module
import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

val apiModule: Module = module {

single<ApiInterface> { get<Retrofit>().create(ApiInterface::class.java) }

single<Retrofit> {
Retrofit.Builder()
.baseUrl(ApiClient.BASE_URL)
.client(get())
.addConverterFactory(get<GsonConverterFactory>())
.build()
}

single<GsonConverterFactory> { GsonConverterFactory.create() }

single<OkHttpClient> {
OkHttpClient.Builder()
.run {
addInterceptor(get<Interceptor>())
build()
}
}

single<Interceptor> {
Interceptor { chain ->
with(chain) {
val newRequest = request().newBuilder()
.addHeader("X-Naver-Client-Id", "33chRuAiqlSn5hn8tIme")
.addHeader("X-Naver-Client-Secret", "fyfwt9PCUN")
.build()
proceed(newRequest)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.mtjin.androidarchitecturestudy.module

import androidx.room.Room
import com.mtjin.androidarchitecturestudy.data.login.source.local.LoginLocalDataSource
import com.mtjin.androidarchitecturestudy.data.login.source.local.LoginLocalDataSourceImpl
import com.mtjin.androidarchitecturestudy.data.search.source.local.MovieDao
import com.mtjin.androidarchitecturestudy.data.search.source.local.MovieDatabase
import com.mtjin.androidarchitecturestudy.data.search.source.local.MovieLocalDataSource
import com.mtjin.androidarchitecturestudy.data.search.source.local.MovieLocalDataSourceImpl
import com.mtjin.androidarchitecturestudy.utils.PreferenceManager
import org.koin.android.ext.koin.androidContext
import org.koin.core.module.Module
import org.koin.dsl.module

val localDataModule: Module = module {
single<MovieLocalDataSource> { MovieLocalDataSourceImpl(get()) }
single<LoginLocalDataSource> { LoginLocalDataSourceImpl(get()) }
single<PreferenceManager> { PreferenceManager(get()) }
single<MovieDao> { get<MovieDatabase>().movieDao() }
single<MovieDatabase> {
Room.databaseBuilder(
get(),
MovieDatabase::class.java, "Movie.db"
)
.allowMainThreadQueries()
.build()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.mtjin.androidarchitecturestudy.module

import com.mtjin.androidarchitecturestudy.utils.NetworkManager
import org.koin.android.ext.koin.androidContext
import org.koin.core.module.Module
import org.koin.dsl.module

val networkModule: Module = module {
single { NetworkManager(get()) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.mtjin.androidarchitecturestudy.module

import com.mtjin.androidarchitecturestudy.data.search.source.remote.MovieRemoteDataSource
import com.mtjin.androidarchitecturestudy.data.search.source.remote.MovieRemoteDataSourceImpl
import org.koin.core.module.Module
import org.koin.dsl.module

val remoteDataModule: Module = module {
single<MovieRemoteDataSource> { MovieRemoteDataSourceImpl(get()) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.mtjin.androidarchitecturestudy.module

import com.mtjin.androidarchitecturestudy.data.login.source.LoginRepository
import com.mtjin.androidarchitecturestudy.data.login.source.LoginRepositoryImpl
import com.mtjin.androidarchitecturestudy.data.search.source.MovieRepository
import com.mtjin.androidarchitecturestudy.data.search.source.MovieRepositoryImpl
import org.koin.core.module.Module
import org.koin.dsl.module

val repositoryModule: Module = module {
single<MovieRepository> { MovieRepositoryImpl(get(), get(), get()) }
single<LoginRepository> { LoginRepositoryImpl(get()) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.mtjin.androidarchitecturestudy.module

import com.mtjin.androidarchitecturestudy.ui.login.LoginViewModel
import com.mtjin.androidarchitecturestudy.ui.search.MovieSearchViewModel
import com.mtjin.androidarchitecturestudy.ui.splash.SplashViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.module.Module
import org.koin.dsl.module

val viewModelModule: Module = module {
viewModel { SplashViewModel(get()) }
viewModel { LoginViewModel(get()) }
viewModel { MovieSearchViewModel(get()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,27 @@ package com.mtjin.androidarchitecturestudy.ui.login

import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.mtjin.androidarchitecturestudy.R
import com.mtjin.androidarchitecturestudy.base.BaseActivity
import com.mtjin.androidarchitecturestudy.data.login.source.LoginRepository
import com.mtjin.androidarchitecturestudy.data.login.source.LoginRepositoryImpl
import com.mtjin.androidarchitecturestudy.data.login.source.local.LoginLocalDataSource
import com.mtjin.androidarchitecturestudy.data.login.source.local.LoginLocalDataSourceImpl
import com.mtjin.androidarchitecturestudy.databinding.ActivityLoginBinding
import com.mtjin.androidarchitecturestudy.ui.search.MovieSearchActivity
import com.mtjin.androidarchitecturestudy.utils.PreferenceManager
import org.koin.androidx.viewmodel.ext.android.viewModel

class LoginActivity : BaseActivity() {
private lateinit var binding: ActivityLoginBinding
private lateinit var preferenceManager: PreferenceManager
private lateinit var loginLocalDataSource: LoginLocalDataSource
private lateinit var loginRepository: LoginRepository
private val viewModel: LoginViewModel by viewModels {
object : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return LoginViewModel(loginRepository) as T
}
}
}
private val viewModel: LoginViewModel by viewModel()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
inject()
initBinding()
initViewModelCallback()
}

private fun inject() {
private fun initBinding() {
binding =
DataBindingUtil.setContentView(this, R.layout.activity_login)
preferenceManager = PreferenceManager(this)
loginLocalDataSource = LoginLocalDataSourceImpl(preferenceManager)
loginRepository = LoginRepositoryImpl(loginLocalDataSource)
binding.vm = viewModel
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,28 @@ package com.mtjin.androidarchitecturestudy.ui.search
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.viewModels
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.mtjin.androidarchitecturestudy.R
import com.mtjin.androidarchitecturestudy.base.BaseActivity
import com.mtjin.androidarchitecturestudy.databinding.ActivityMovieSearchBinding
import com.mtjin.androidarchitecturestudy.utils.MyApplication
import org.koin.androidx.viewmodel.ext.android.viewModel


class MovieSearchActivity : BaseActivity() {

private lateinit var binding: ActivityMovieSearchBinding
private lateinit var movieAdapter: MovieAdapter
private lateinit var myApplication: MyApplication
private val viewModel: MovieSearchViewModel by viewModels {
object : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return MovieSearchViewModel(myApplication.movieRepository) as T
}
}
}
private val viewModel: MovieSearchViewModel by viewModel()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_movie_search)
inject()
initBinding()
initViewModelCallback()
initAdapter()
}

private fun inject() {
myApplication = application as MyApplication
private fun initBinding() {
binding = DataBindingUtil.setContentView(this, R.layout.activity_movie_search)
binding.vm = viewModel
binding.lifecycleOwner = this
Expand Down