안드로이드 스튜디오에서 java를 kotlin으로 자동 변환해 주지만 완벽하게 되지는 않아서
직접 고쳐줘야 하는 부분들이 있다.
그런 부분들을 발견할 때마다 추가할 예정.
'XX' has private access in 'XX'
코틀린 파일에서 선언된 변수를 자바 파일에서 사용하고자 할 때,
해당 변수가 public 으로 선언되어 있음에도 불구하고 이런 메시지와 함께 에러가 발생하게 된다.
이 경우 해당 변수 앞에 @JvmField 를 선언해주면 에러가 발생하지 않는다.
@JvmField var test: String = "Test"
Break and Continue Labels
중첩된 조건문이나 for문, 또는 중첩된 메서드나 인터페이스 등에서 단순하게 return, break문으로 처리가 안되는 경우 빠져나오는 구간을 직접 지정해 줄 수 있다.
(java 에서는 해당 구간을 빠져나오지만 kotlin 에서는 단순히 return, break문만 써서는 에러가 발생)
사용 방법은 "문자열@" , "@문자열" 이며 아래와 같이 사용 가능 하다.
문자열은 자율적으로 작성할 수 있다.
loop@ for (i in 1..100) { for (j in 1..100) { if (...) break@loop } }
fun foo() { ints.forEach lit@ { if (it == 0) return@lit print(it) } }
실제로 겪은 현상은 Rx의 각각의 interface를 매개변수로 받아서 처리하는 부분에서,
onNext에 해당하는 구간 안에 if 조건문에 따른 return 구문이 있었는데
이 부분에서 정확히 변환을 시켜주지 못해서 onNext 구간에 아래와 같이 처리해 줬다.
onNext@ {
event ->
Log.d(TAG, "event")
return@onNext
}
public static 메서드
public static test() {} 와 같은 코드를 kotlin으로 변경시키면 아래와 같은
형태로 만들어진다.
companion object {
fun test() {}
}
하지만 이렇게 만들어진 test() 메서드를 TestClass.test() 와 같이 호출해주려고
하면 test() 메서드를 찾지 못한다.
TestClass.test() 와 같이 호출해 주기 위해서는 @JvmStatic 을 메서드 앞에 붙여주면 된다.
companion object {
@JvmStatic fun test() {}
}
이렇게 하면 TestClass.test()와 같이 호출할 수 있다.
Dagger2 Inject
Dagger 2 를 사용하는 Java 파일을 Kotlin으로 변환시키면 dagger 관련해서
온갖 에러들이 발생하는 경우가 발생하는 경우가 있다.
나같은 경우에는 수많은 Dagger 에러와 함께 아래와 같은 에러 메시지가 발생하였다.
TestClass cannot be provided without an @Inject constructor or from an @Provides-annotated method.
분명 어떤 클래스에서, 어떠한 이유로 문제가 발생한지는 나와있는데 어떤식으로 해결하라는 것인지
감이 안잡혔다. Provider도 정상적으로 선언되어있고 Inject도 정상적으로 선언되어있고,
게다가 Java코드였을 때에는 분명히 잘 됐던 코드였었는데.
어쨌건 여기저기 찾아보고 이것저것 시도해보면서 해결은 되었다.
Dagger 관련 부분에서 아래와 같은 코드가 있었는데
@Inject
TestApi testApi;
Kotlin으로 변경시 아래 처럼 변환이 되었는데 이게 문제였던 것이였다.
@Inject
internal var testApi: TestApi? = null
해결 방법은 아래와 같이 변수 앞에 lateinit을 선언해 주면 된다.
@Inject
lateinit internal var testApi: TestApi
lateinit으로 초기화를 할 경우 null을 사용해서 초기화 하는것이 불필요 하다.
(lateinit 에 대한 설명은 http://thdev.tech/kotlin/2017/02/08/Kotlin-lateinit-lazy.html 를 참조.)
Retrofit2
retrofit2 사용파면서 파일 업로드를 위해 인자값을 넘길 때 Map<String, RequestBody>과 같이 사용하고 있던중, retrofit2 관련 클래스를 코틀린 형태로 바꿨는데 아래와 같은 에러가 발생하였다.
Parameter type must not include a type variable or wildcard: java.util.Map.....
해결 방법은 Map부분을 MutableMap이나 HashMap로 바꿔주면 된다.
before
fun request(@PartMap params: Map<String, RequestBody>): Flowable<Result>
after
fun request(@PartMap params: HashMap<String, RequestBody>): Flowable<Result>