월 15,400원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨냉동코더의 알기 쉬운 Modern Android Development 입문
EditText 는 액티비티가 재생성되어도 값이 남아있던데 이유가 궁금해요
책검색 구현 내용 설명해주실때EditText 는 액티비티가 재생성되어도 값이 남아있던데 조금만 더 자세하게 왜 그런지 키워드만이라도 좀 알려주실까요? EditText 에서 어떤부분을 찾아봐야 알 수 있는지 모르겠네요..아 질문등록하고 좀 더 찾아봤는데 saveEnabled 속성으로 알아보면되겠네요View는 기본적으로 saveEnabled="true"가 기본값 입니다.
- 해결됨냉동코더의 알기 쉬운 Modern Android Development 입문
ViewModel 생성시 왜 초기값을 받지 않도록 했을까요?
구글은 왜 ViewModel 생성시 초기값을 ViewModel 생성자로부터 받지않고ViewModelProvider , Factory 를 이용해서 ViewModel 을 생성하나요?!OOP 개념과 관련되어있을것같은데 여쭤봅니다..!
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
Room DB에 id 항목 추가
즐겨찾기 아이템 삭제시 undo를 할 때 아이템이 원래있었던 위치로 오게 하려면 autoGenerate의 id항목을 추가해 primaryKey로 지정하면 된다고 하셨는데요Book 이 API로 책정보를 가져오는 용도로도 사용해서 Search할 때 documents에 id가 없다는 에러가 발생합니다이를 해결하기 위해선 DB에 사용할 Entity를 따로 생성해 id항목을 추가해주어야 하나요?
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
안녕하세요. 용어에 대해 질문이 있어 글 남깁니다.
안녕하세요. 강의 잘듣고 있습니다.다만, 제가 이 강의부터 시작해서 그런지 용어에 대한 개념이 헷갈립니다. util 디렉토리와 source.kt 파일의 역할은 정확히 무엇인가요?util 디렉토리에 들어가는 파일들의 내용은 무엇이고,DataSource의 역할이 무엇인지 궁금합니다 !감사합니다..
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
paging config pageSize 관련
안녕하세요 강의 잘듣고 있습니다.실무적용하다가 궁금해서 질문드립니다.1.현재 개발중인 서비스가 서버에서 데이터를 가져올때 요청한 갯수만큼 가져올수 있는데 만약 10개를 서버에 요청한다면 PagerConfig의 pageSize 인자도 10개로 맞춰줘야 하나요?2.북서치예제에서 PAGING_SIZE 가 17이면 NPE가 발생해서 앱이 종료되는데 이유를 모르겠습니다.3.현재 하단에 fragment 탭 4개가 있고 한개의 탭안에 2개의 자식 fragment가 중첩되는있는 구조인데 둘다 paging + stateflow 를 사용하고 있습니다. 그런데 다른 fragment 이동했다가 다시돌아오면 북서치예제처럼 스크롤이 마지막 포지션을 유지하는 것이 아니고 리스트를 새로 그려서 맨위로 올라갑니다. 스크롤을 유지하려면 어떻게 해야될까요? 그리고 리스트를 그려줄때 깜빡이는 현상이 있는데 북서치예제처럼 부드럽게 그려주려면 어떻게 해야될까요?질문이 너무 중구난방이라 죄송합니다..
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
Flow lifecycleScope에 대해서 궁금한 게 있습니다.
안녕하세요.lifecycleScope.launchWhenStarted와 repeatOnLifecycle의 차이점과 어느때 각각 사용하면 좋을지 궁금합니다.
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
강의내용 블로그 포스팅 관련 질문
안녕하세요 우선 강의 너무 잘 듣고 있습니다. 좋은 강의 제공해주셔서 감사드립니다. 다름이 아니라 강의를 들으며 공부한 내용을 바탕으로 제 생각과 설명을 덧붙혀 블로그에 공개 포스팅하는게 문제가 될지 궁금해 여쭤봅니다!코드와 내용 일부를 수정하고 제 의견 위주로 적으려는데 괜찮을까요??
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
Transformations.switchMap 함수의 리턴
배경지식val 키워드는 런타임 시점에 한번 초기화 된 이후다시 초기화 하지 못한다고 알고 있습니다.검색해보니 map 함수는 값을 리턴하고, switchMap 함수는 LiveData 를 리턴한다고 합니다. 질문이미 초기화 된 val 에 새로운 LiveData 객체를 리턴하면, 할당 된 포인터 주소의 메모리 안에 덮어 씌워지는 것 인가요 ? val 에 처음 할당 된 메모리의 양보다 많은 데이터를 리턴하게 되면 StackOverFlow 가 발생하나요 ?가리키는 heap 영역의 메모리가 유연하게 증가하나요 ? 저의 부족하거나 잘못된 배경지식으로 접근해 질문하고 있다면, 학습 방향의 키워드나 힌트를 알려주세요 ㅠ_ㅠ
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
PagingAdapter에서 웹뷰로 이동하고 나서 뒤로가기를 눌렀을 때 깜빡임 현상
책을 검색하고 나서 어느정도 밑으로 쭉 스크롤을 하고 나서 어느 책 하나를 클릭해서 웹뷰로 들어가고 뒤로가기를 누르면 웹뷰로 들어가기 전 페이지가 보이는게 아니라 다시 첫페이지를 보여주는 이슈가 있습니다.원인이 무엇일까요??? 추가Log를 찍어보니 웹뷰로 들어갔다 뒤로가기를 누르면 Api가 다시 page1을 불러오는 것을 확인하였습니다. 아무래도 Fragment를 이동하고 다시 돌아오면서 PagingSource가 다시 만들어져서...? page1을 다시 호출하는 것 같습니다 ㅠ
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
ViewModel이 Repository 인터페이스를 주입받는 이유
이 부분의 궁금증이 해결되지 않아 여쭤봅니다!ViewModel에서 Repository를 생성자로 받을 때 그냥 @Inject 키워드를 써서 클라스를 주입받지 않고 인터페이스를 굳이 만들어 @Module 로 바인딩을 하고 주입받는지 이유가 궁금합니다.즉 왜 Reposiory와 RepositoryImpl을 나누는 걸까요?
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
오버라이드 한 waitFor 메서드와 다른 라이브러리의 차이점은 뭘까 궁금합니다.
영상 6:38~7:30초에 waitFor메서드에 대해서 이것도 권장되는 방법인지에 대한 의문과.. 궁금해서 스택오버플로도 들어가보긴했지만... 잘모르겠고,Espresso idling resources와의 차이점? 같은거에 대해서 아실분이 계시다면 답글을 남겨주시면 감사하겠습니다.굳이 억지로 시간내서 찾아주실 필요는 없고..오다가다 아시는분 계시면 링크하나 던져주시면 감사하겠습니다! =================// 제가 대충 분석한 내용(?)waitFor()에서 perform()을 오버라이드 한 부분에loopMainThreadForAtLeast()가 implementation된 부분을 구경해봤는데,(윈도우 단축키: '컨트롤 알트 클릭' or '컨트롤 알트 B')UiControllerImpl.loopMainThreadForAtLeast()가 구현된 코드를 볼 수 있었지만..아마도, 핸들러에 딜레이 준 만큼 넣어뒀다가,메인스레드가 idle일때 핸들러를 돌려주는 소스인듯한데. 정확히 분석이 안되는군요.
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
sdk33에서 robolectric빌드에러 나는분들 참고하세요.
질문은 아니고, 다른분들 에러생기면 보시라고 올립니다.(자유주제나 스터디 탭에 올리면 안보실거같아서 질문에 올립니다.) 디펜던시들 최신으로 올리면서,sdk33으로 올려두게 되었는데,sdk33에서 robolectric:4.8.1버전을 사용하게 되면 빌드에러가 나옵니다. 이때, robolectric:4.9.1로 올리면RobolectricTestRunner던, AndroidJUnit4를 쓰든테스트가 성공합니다.(이상한 에러로그가 뜨긴하지만..) // Robolectric 리드미 참고https://github.com/robolectric/robolectric// 해당 이슈 참고https://github.com/robolectric/robolectric/issues/7590// 위 이슈 해결된 pr 참고https://github.com/robolectric/robolectric/pull/7601
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
오기된 부분이 있는 것 같습니다.
아래 영상에서Practice11-build.gradle을 KTS로 마이그레이션하기 (KTS, buildSrc) 8:55초에서// Lifecycle 부분의3번째 디펜던시가LIFECYCLE_SAVEDSTATE이 되어야 하는 것 같은데자동완성 하면서 잘못들어간거 같네요근데 오기된 상태에서도 빌드하고, adb kill 했을 때 정상적으로 작동하네요. // adb 명령어 참고1adb devices // adb 명령어 참고2adb -s emulator-5554 shell am kill com.example.booksearchapp ==============더블쉬프트 눌러서 Files탭에서 SavedStateHandle 클래스 검색해보면해당 라이브러리가 들어가있는데,이게 이전에 빌드 돌리면서 그래들캐시?에 들어가 있는건지, (혹시나 해서 invalidate cache - clear file cache and local history 도 체크해서 돌려봤는데 그대로 담겨있음)다른 디펜던시에 같이 담겨있어서 되는 건지.. 허접이라,, 디펜던시 가져오는거에 대해서는 디버깅을 잘못하겠군요..ㅜ 여튼, 이 부분 공부 하시는 분들 참고 하실까해서..글 남겨둡니다 //그리고 팁으로? git걸어뒀으면, buildSrc 자동 생성되는 파일이 있으니 .gitignore에 아래 두줄 추가 작성해야하지 않을까 싶군요./buildSrc/.gradle/buildSrc/build
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
Coroutine에 관하여
Kotlin Flow 부분을 학습하며 Coroutine을 공부하던 중 궁금한 점이 생겨 질문올립니다!!다음과 같이 runBlocking안 launch를 통해 coroutineScope 안에서 thread가 실행되는 것은 이해가 갔습니다! 여기서 launch 밖 코드(1)은 어디서 실행되는 것인지 알 수 있을까요???fun main() = runBlocking<Unit> { launch { //main thread for (k in 1..3){ println("I'm not blocked $k") delay(100) } } println("hello") //(1) }
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
WorkManger 반복되는거 확인하는 테스트에 대한 노하우가 있으실까요
CacheDeleteWorker - doWork()가 반복적으로 작동하는지영상 12:00쯤에 시간을 돌려서 Periodic하게 실행되는지 테스트해보시는데,시간을 어떻게 돌리시는 걸까요.?그냥 안드로이드 설정에서, 시간설정 자동으로 되어있는걸 수동으로 바꿔서 시간을 변경하시는걸까요...?저는 수동으로 시간을 바꿔도.. 테스트가 제대로 안되는듯합니다 ㅜ 테스트 간편히 하려고,workRequest에서 repeatInterval 값 10,TimeUnit.SECONDS로 바꿔봐도..App Inspector에서, Database Inspoector로 보면,WorkSpec에서 id값이 변하긴하던데..interval_duration값이 90,000으로(15분)으로 그대로 남아있는거 같고..? 앱을 지우고 재 설치해도 저 db정보가 남아있는듯한데.. 테스트해보기가 어질어질 하군요.이거 테스트 노하우가 있으시다면 알려주세요..!!!?
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
Moshi 관련 Exception error
2022-12-12 09:04:14.193 11869-11909/com.example.booksearchapp E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1 Process: com.example.booksearchapp, PID: 11869 java.lang.IllegalArgumentException: Unable to create converter for class com.example.booksearchapp.data.model.SearchResponse for method BookSearchApi.searchBooks at retrofit2.Utils.methodError(Utils.java:54) at retrofit2.HttpServiceMethod.createResponseConverter(HttpServiceMethod.java:126) at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:85) at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39) at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202) at retrofit2.Retrofit$1.invoke(Retrofit.java:160) at java.lang.reflect.Proxy.invoke(Proxy.java:1006) at $Proxy2.searchBooks(Unknown Source) at com.example.booksearchapp.data.repository.BookSearchRepositoryImpl.searchBooks(BookSearchRepositoryImpl.kt:14) at com.example.booksearchapp.ui.viewmodel.BookSearchViewModel$searchBooks$1.invokeSuspend(BookSearchViewModel.kt:18) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664) Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@5775e41, Dispatchers.IO] Caused by: java.lang.RuntimeException: Failed to find the generated JsonAdapter class for class com.example.booksearchapp.data.model.SearchResponse at com.squareup.moshi.internal.Util.generatedAdapter(Util.java:590) at com.squareup.moshi.StandardJsonAdapters$1.create(StandardJsonAdapters.java:61) at com.squareup.moshi.Moshi.adapter(Moshi.java:146) at com.squareup.moshi.Moshi.adapter(Moshi.java:106) at retrofit2.converter.moshi.MoshiConverterFactory.responseBodyConverter(MoshiConverterFactory.java:89) at retrofit2.Retrofit.nextResponseBodyConverter(Retrofit.java:362) at retrofit2.Retrofit.responseBodyConverter(Retrofit.java:345) at retrofit2.HttpServiceMethod.createResponseConverter(HttpServiceMethod.java:124) ... 16 more Caused by: java.lang.ClassNotFoundException: com.example.booksearchapp.data.model.SearchResponseJsonAdapter at java.lang.Class.classForName(Native Method) at java.lang.Class.forName(Class.java:454) at com.squareup.moshi.internal.Util.generatedAdapter(Util.java:564) ... 23 more Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.booksearchapp.data.model.SearchResponseJsonAdapter" on path: DexPathList[[zip file "/data/app/~~ewlJIwWx_qkVa9ZkFq_uYw==/com.example.booksearchapp-D0tkT_fBZhzV4uo7HrITvw==/base.apk"],nativeLibraryDirectories=[/data/app/~~ewlJIwWx_qkVa9ZkFq_uYw==/com.example.booksearchapp-D0tkT_fBZhzV4uo7HrITvw==/lib/x86_64, /system/lib64, /system_ext/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) ... 26 moreSearchFragment에 RecyclerView와 searchBooks를 추가 한뒤 빌드하여 검색창에 텍스트를 입력하면 앱이 바로 죽는 현상이 나타나고 있어 질문드립니다.Moshi에서 JasonAdapter를 찾을 수 없다고 하는데 혹시 의존성 세팅이 다르게 되어 있어서일까요?plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' /*add ksp*/ id("com.google.devtools.ksp").version("1.6.10-1.0.4") id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' } android { compileSdk 32 defaultConfig { applicationId "com.example.booksearchapp" minSdk 23 targetSdk 32 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } buildFeatures { viewBinding true } } dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'com.google.android.material:material:1.7.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.4' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' /* Retrofit */ implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-moshi:2.9.0' /* Moshi */ implementation 'com.squareup.moshi:moshi:1.13.0' implementation("com.squareup.moshi:moshi-kotlin:1.14.0") ksp("com.squareup.moshi:moshi-kotlin-codegen:1.14.0") /* Okhttp */ implementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0")) implementation("com.squareup.okhttp3:okhttp") implementation("com.squareup.okhttp3:logging-interceptor") /* Lifecycle */ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' /*Add Coroutine */ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1' /*Add Coil*/ implementation 'io.coil-kt:coil:1.3.2' /*Add RecyclerView*/ implementation 'androidx.recyclerview:recyclerview:1.2.1' }제 Build.gradle 설정입니다. kapt 사용시 빌드과정에서 문제가 있어 ksp로 변경했고 이후 빌드와 run은 성공적으로 진행하는 것 확인했습니다..
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
Data Class 강의 중 Copy 내용
강의 복습중입니다! 강의에서 Data Class의 Copy를 얕은 복사라고 설명해주셨는데 깊은 복사 아닌가요...?data class Person(var name: String, var age: Int) fun main() { val person1 = Person("Bob", 22) val person2 = person1.copy(name = "James") println(person1.hashCode()) println(person2.hashCode()) }얕은 복사라면 해당 해시코드가 같아야 정상인데 출력해보니 다른 값이 나와서요!
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
안드로이드 테스트 Hilt 적용시 문제
DaoTest에서 Hilt를 적용하기 전까지는 정상적으로 동작하다가 영상 그대로 Hilt를 적용하니까 사진과 같이 테스트 자체가 안돌아갑니다 ㅠㅠ 2시간동안 구글링하며 여러 의존성도 추가해보고 했는데도 계속 이상태여서 질문드립니다..! 추가) 죄송합니다 testInstrumentationRunner 에 앱 패키지 이름 적으면서 오타가 있었습니다 죄송합니다....하
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
Room과 Flow의 관계
책을 즐겨찾기를 추가하고 즐겨찾기 탭으로 갔을때 즐겨찾기 했던 책이 자동으로 Recyclerview에 추가되어있는 모습을 볼 수 있는데 이는 Flow, 즉 데이터 스트림을 사용했기 때문인거죠?? 즉 FavoriteFragment의 onViewCreated에 있는 함수가 collect 트리거를 작동시키면 자동으로 Room에 추가된 데이터가 RecyclerView에 추가되는 형식이라고 이해했습니다.근데 앱을 조금 변경하여 특정버튼을 눌러야 DB에서 데이터를 가져오는 로직으로 (즉 버튼을 눌러야 ViewModel의 getFavoriteBook을 호출하는 형식) 변경하였는데 버튼을 누르지 않아도 알아서 ViewModel에서 즐겨찾기 데이터가 갱신이 되더라고요...ㅇㅅㅇ 분명 collect 트리거를 작동시키지 않았는데요
- 미해결냉동코더의 알기 쉬운 Modern Android Development 입문
CalendarView 사용에 관해 질문있습니다.
유투브와 인프런 강의를 들으며 개인적으로 어플리케이션을 만들던 중 기능구현에 문제가 발생했습니다. CalendarView에서 리스트에 담긴 특정날짜들을 읽어와해당하는 날짜들을 CalendarView에서 비활성화 하고 싶습니다. 혼자 검색을 해보았지만 번역된 방법을 보아도 모르겠어서 이렇게 질문드립니다,