Project 생성
project gradle: hilt 적용
buildscript {
ext {
compose_ui_version = '1.3.3'
hilt_version = '2.44'
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.2' apply false
id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
id 'com.google.dagger.hilt.android' version '2.44' apply false
}
app gradle : Retrofit, Gson conveter, Hilt, Coroutine, Coroutine Lifecycle scopes 적용
plugins {
...
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
android {
...
composeOptions {
kotlinCompilerExtensionVersion '1.4.4'
}
...
}
dependencies {
// Hilt-dagger
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"
// implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03" => 필요 없음 있으면 애러남
kapt "androidx.hilt:hilt-compiler:1.0.0"
implementation "androidx.hilt:hilt-navigation-compose:1.0.0"
// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4'
// Coroutine Lifecycle scopes
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// Gson converter
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
...
}
build error : ... dagger.hilt.android.internal.lifecycle.DefaultActivityViewModelFactory' could not be resolved.
https://salmonpack.tistory.com/34
원인은 바로 implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
build.gradle(:app)
dependencies {
...
// hilt
implementation 'com.google.dagger:hilt-android:2.44'
kapt 'com.google.dagger:hilt-compiler:2.44'
kapt 'com.google.dagger:hilt-android-compiler:2.44'
// implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
...
}
Hilt 2.31에서 ViewModel 주입 방법이 바뀌었다고 합니다.
이제는 androidx.hilt:hilt-lifecycle-viewmodel 라이브러리 없이도
@HiltViewModel만 사용한다면 문제가 없다고 하네요.
=====================================
project package : component, data, di, model, network, repository, screen, util
model > json import
| json을 인터넷에서 임포트하기 위해서는 file > setting > Plugins > "Json to kotlin Class" => 설치 , 재시작 new > kotlin data class file from json > 화면에 우클릭 > Retrieve content from Http url > URL을 입력 class name : Question => QuestionItem 이 자동 생성됨 프로젝트에서 사용하는 json : https://raw.githubusercontent.com/itmmckernan/triviaJSON/master/world.json |
root> Application 파일 생성(@HiltAndroidApp 추가)
@HiltAndroidApp
class TriviaApplication : Application() {
}
manifests 수정(인터넷 접속 허용, application 추가)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name=".TriviaApplication"
...
</application>
</manifest>
di> AppModule 생성(object , singletone)
util> constants 생성(Base url)
object Constants {
// https://raw.githubusercontent.com/itmmckernan/triviaJSON/master/world.json
const val BASE_URL = "https://raw.githubusercontent.com/itmmckernan/triviaJSON/master/"
}
network> QuestionApi 생성(singletone, interface)
@Singleton
interface QuestionApi {
@GET("world.json")
suspend fun getAllQuestions(): Question
}
di> AppModule : Retrofit 객체 생성
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Singleton
@Provides
fun provideQuestionApi(): QuestionApi {
val retrofit = Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
// val api = retrofit.create(QuestionApi::class.java)
// val user: Response<User> = api.getUser().execute()
return retrofit.create(QuestionApi::class.java)
}
}
repository > QuestionRepository 생성(Inject)
class QuestionRepository @Inject constructor(private val api: QuestionApi) {
private val listOfQuestions
// = ArrayList<QuestionItem> (emptyList())
= DataOrException<ArrayList<QuestionItem>,
Boolean,
java.lang.Exception>()
}
data> DataOrException 생성(wrapper class)
data class DataOrException <T, Boolean, E: Exception> (
var data : T? = null,
val loading: Boolean? = null,
var e: E? = null )
==> wrapper class를 만드는 이유는 받아온 데이터에 추가 적인 정보를 넣어서 쉽게 변경 가공하기 위함

===== 여기 까지 하면 기본 적으로 데이터를 가져오는 것은 되는 것임(json -> kotlin object) =====
MainActivity에 데이터 적용하기
viewModel을 가지고 와서 데이터를 적용(기본적으로 hiltViewModel을 적용하면 됨)
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Json_Retrofit_triviaTheme {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
HomeScreen()
}
}
}
}
}
@Composable
fun HomeScreen(viewModel: QuestionViewModel = hiltViewModel() ) {
Questions(viewModel)
}
@Composable
fun Questions(viewModel: QuestionViewModel) {
val questions = viewModel.dataWrapped.value.data?.toMutableList()
if (viewModel.dataWrapped.value.loading == true) {
Log.d("로딩", "Questions Loading...")
} else {
Log.d("로딩", "Questions Loading.. STOPPED...")
questions?.forEach { item ->
Log.d("태그", "Questions : ${item.question}, ${item.category}")
}
}
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
Json_Retrofit_triviaTheme {
HomeScreen()
}
}
화면 구성
'Android-jetpack Compose' 카테고리의 다른 글
| room db 실행 시 compile은 잘되나 튕김 발생 (0) | 2023.04.24 |
|---|---|
| jetpack compose : (Step 2) ☞ ViewModle(NoteApp) (0) | 2023.04.02 |
| jetpack compose : (Step 1) Without ViewModle(NoteApp) (0) | 2023.04.02 |
| jetpack compose : (Step 3) ViewModel ☞ DI(Hilt), Room(NoteApp) (0) | 2023.04.02 |
| jetpack compose - dependency injection, Room 참고 자료-사이트 (0) | 2023.04.02 |