[문제 상황]
//현재 달에 대한 정보
@RequiresApi(Build.VERSION_CODES.O)
val dateMonth: Int = LocalDateTime.now().format(DateTimeFormatter.ofPattern("MM")).toInt()
avd로 컴파일 할 때는 아무런 이상이 없었는데,
개인 모바일 디바이스로 app을 실행하자 위의 코드에서 오류가 발생했다.
오류의 내용을 아래와 같다.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.todolistjinuemong, PID: 4223
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/LocalDateTime;
LocalDateTime.now()는 java 8 버전을 사용한다.
java 8 버전을 사용하기 위한 세팅을 해주지 않아서 오류가 발생하는 것 같다.
[문제 해결]
자바 8 언어 기능 및 API 사용 | Android 개발자 | Android Developers
자바 8과 관련된 개발 문서를 읽어봤다.
"소스 코드나 모듈 종속 항목 중 하나에서 이러한 메서드 중 하나를 사용하는 경우 minSdkVersion 26 이상을 지정해야 합니다. 그러지 않으면 다음 오류가 발생합니다."
문제 해결을 위해서 app.Gradle의 minSdk를 26으로 수정 후에 컴파일 해봤다.
원인은 앱을 실행 진행 중인 디바이스에 있었다.
내 디바이스의 API는 25인데 API 26 버전의 기능을 사용하려고 해서 문제가 발생했다.
Android 스튜디오 프로젝트 설정 | Maps SDK for Android | Google Developers
이와 관련된 공식 문서를 읽어봤다.
에러가 발생한 LocalDateTime에 관련된 문서는 아니였지만 비슷한 문제를 다루고 있었다.
"앱이 API 수준 28(Android 9.0) 이상을 타겟팅하는 경우 AndroidManifest.xml의 <application> 요소 내에 다음 선언을 포함해야 합니다."
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
문제를 해결하기 위해서 Manifest에 library 관련 선언을 해주었다.
Ljava/time/LocalDateTime에서 L을 제외한 부분을 name에 넣어준다.
<uses-library
android:name="java/time/LocalDateTime"
android:required="false" />
계속 같은 문제가 발생한다..
sdk가 26 이상인 디바이스에서는 성공적으로 실행되나 25 이하인 앱에서는 같은 오류가 반복된다.
어쩔 수 없이 LocalDateTime 대신에 Calendar의 인스턴스로 날짜 정보를 불러오는 방법을 사용했다.
val date = Calendar.getInstance().time
val dateMonth: Int = SimpleDateFormat("MM", Locale.KOREA).format(date).toInt()
이제 오류가 발생하지 않는다.
java 8 관련 기능은 minSdkVersion 26이상의 앱을 개발할 때만 사용해야겠다.