[안드로이드 공부]/코틀린 8

Inheritance from an interface with '@JvmDefault' members is only allowed with -Xjvm-default option

Inheritance from an interface with '@JvmDefault' members is only allowed with -Xjvm-default option viewModel 에 param을 추가하였더니 viewModel Factory가 필요하고, 추가 하니 위와 같은 에러가 나왔다~ 버전 충돌 문제인데~ build.gradle.app 에 kotlinOptions { jvmTarget = '1.8' freeCompilerArgs += [ '-Xjvm-default=enable' ] } 또는 tasks.withType(KotlinCompile).configureEach { kotlinOptions { freeCompilerArgs += [ "-Xjvm-default=all", ] } }..

android worker ClassNotFoundException

Room 에서 DB 가 만들어지고, 초기화를 할 때 OnCreate() 에서 아래와 같이 워커를 불러서 작업을 하는데, val request = OnTimeWorkRequestBuilder().build() WorkManager.getInstance(context).enqueue(request) enqueue 에 작업을 넣으려고 하면 아래와 같이 요상한 에러가 난다. 아무리 인터넷을 뒤져도 답이 없다. E/AndroidRuntime: FATAL EXCEPTION: arch_disk_io_0 java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/work/impl/utils/futures/AbstractFuture; Caused by: java.l..

smart cast to is impossible because is a mutable property that could have been changed by this time

변경될 수 있는(mutable/var) 타입을 캐스팅 할 경우 문제가 생긴다. 이 경우에는 val 불변 타입으로 새로운 변수에 할당 한 뒤에 캐스팅을 해야 한다. private val plantDetailViewModel: PlantDetailViewModel by viewModels { InjectorUtils.providePlantDetailViewModelFactory(requireActivity(), args.plantId) } val binding = DataBindingUtil.inflate( inflater, R.layout.fragment_plant_detail, container, false ).apply { viewModel = plantDetailViewModel //error bea..

[MVVM] LiveData와 ViewModel Observer로 연결

Repository의 Data가 변경 되었을 때 UI에 알리기 위해서는 ViewModel이 관찰을 하고 있어야 한다. UI(V)는 보통 onCreate()에서 VM을 생성하고, VM은 Repository를 생성한 뒤 M과 Dao를 통해 연결 되는데, 이 Dao를 LiveData로 구성하면 ViewModel이 지켜 볼 수(obsever) 있게 된다. 연결(MVVM) onCreate/onCreateView 실행이 되면서 viewModel 생성 작업과 이후 연결 작업이 실행 된다. Fragment.kt private val plantDetailViewModel: PlantDetailViewModel by viewModels { InjectorUtils.providePlantDetailViewModelFacto..

코틀린 생성자와 위임

주 생성자와 부 생성자 2가지로 나뉘며, 주 생성자는 클래스 선언 시 가시성 접근자(없으면 클래스 명) 뒤에 선언한다. class Car private constructor(_name: String) 자바는 부 생성자 처럼 클래스 내부에 선언 한다 private class Car { class(String name) } 부 생성자는 클래스 내부에서 파라미터를 달리하여 만든다. class Car private constructor(_name: String) { constructor(value: Int)} 클래스 생성 시 생성자를 정의하지 않으면 컴파일러는 인자가 없는 디폴트 생성자를 만든다 주 생성자 class Car constructor(_name: String){ val name : String ini..

추상클래스(abstract)와 인터페이스(interface)

차이점 추상 클래스는 상속과 필수구현을 위해 인터페이스는 필수구현을 위해 추상 클래스 클래스 내에 추상 메서드가 하나 이상 포함 되거나, abstract 로 정의 된 경우 추상 메서드가 하나라도 있으면 class 앞에 abstract 를 붙여야 함 추상 메서드는 구현 되지 않으며 상속받은 클래스에서만 구현되어야 한다. abstract 에는 final 을 붙일 수 없다. 이미 open 이다 생성자, 전역 변수도 선언 할 수 있고, 메서드 내용이 있을 수도 있다. 다중 상속 안됨 추상 클래스는 직접 생성될 수 없으며, 다른 클래스를 통해 생성되어야 한다. 직접 Car() 로 생성하면 아래와 같은 에러가 나타난다. Cannot create an instance of an abstract class abstra..

코틀린 Scope; apply, also, run, with, let

Scope 함수는 인스턴스의 속성, 함수를 영역내에서 분리해서 사용 할 수 있다. 깔끔하고, 가독성을 높여 준다. apply / also 인스턴스 반환 run(with) /let 최종값 반환 apply 인스턴스(클래스)를 생성한 후 변수에 담기 전 초기화 과정을 수행 할 때 인스턴스 생성 후 .apply{ } 스코프 내에서 인스턴스의 .이름 없이 바로 사용 가능 즉, 인스턴스 생성 하고, 변수에 변경되거나 초기화 값을 넣은 다음 할당 하게 된다. class Book(var title: String, var number:Int){} var a = Book("a", 5).apply{ title = "abcde" + name} 인스턴스가 그대로 반환 된다 run apply 와 같으나, 마지막 구문이 반환 된다..