⚠️ 2021.01.25에 작성된 글입니다 ⚠️
문제 상황
...
FirebaseFirestore.getInstance().collection(...).document(...)
.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot != null) {
TempItem tempItem = documentSnapshot.toObject(TempItem.class);
...
Cloud FireStore를 사용하여 데이터를 가져오는 것을 테스트 하던 중, toObject() 메소드(line 8)에서 에러가 발생했다. 에러 메시지는 다음과 같았다.
java.lang.RuntimeException:Could not deserialize object. Class {에러 발생 액티비티명}$TempItem does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped
해석하면, "1)인자가 없는 생성자가 없다, 2)ProGuard를 사용한다면 해당 클래스의 생성자가 stripped되지 않게 해라" 라는 뜻이다.
해결
step1. 인자가 없는 생성자 있는지 확인하기
inner class인 TempItem 클래스 안에는 인자가 없는 생성자가 있었다.
class TempItem {
...
// 인자가 없는 생성자
public TempItem(){
}
...
}
구글링을 하면 클래스의 변수를 초기화하라는 이야기가 있어 초기화도 해보았지만 도움이 되진 않았다.
step2. ProGuard 사용 여부 체크하기
ProGuard란?
Proguard is free Java class file shrinker, optimizer, obfuscator, and preverifier. It detects and removes unused classes, fields, methods, and attributes.
Mobile app development companies
use proguard in android , it optimizes bytecode and removes unused instructions. It renames the remaining classes, fields, and methods using short meaningless names.
- PEFROMATIX
안드로이드 앱의 코드를 최적화하여 필요 없는 클래스나 제어문들을 최적화하는 등의 작업을 하는 것이다.
앱을 최대한 작게 만들려면 출시 빌드에 축소를 사용 설정하여 미사용 코드와 리소스를 삭제해야 합니다. 축소를 사용하면 앱 클래스와 멤버의 이름을 줄이는 난독화 및 앱 크기를 추가로 줄이는 더 공격적인 전략을 적용하는 최적화 기능을 활용할 수도 있습니다. 이 페이지에서는 R8이 프로젝트에서 컴파일 시간 작업을 하는 방법과 작업을 맞춤설정하는 방법을 설명합니다.
Android Gradle 플러그인 3.4.0 이상을 사용하여 프로젝트를 빌드하는 경우 플러그인은 더 이상 ProGuard를 사용하여 컴파일 시간 코드 최적화 작업을 하지 않습니다. 대신 플러그인은 R8 컴파일러를 이용하여 다음의 컴파일 시간 작업을 처리합니다.
- Android developer site
ProGuard를 검색하면 나오는 안드로이드 개발자 홈페이지의 글이다.
안드로이드에서는 ProGuard를 사용해 코드 최적화 작업을 했음을 확인할 수 있다.
안드로이드 프로젝트의 ProGuard 사용 여부 확인하기
(build.gradle(:app)>buildTypes>release)
...
android {
...
buildTypes {
release {
...
//해당 코드가 있다면 ProGuard를 사용 중인 것
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
...
즉 문제점은 ProGuard를 사용했기 때문에
class TempItem {
...
}
이 TempItem에 영향이 가 생성자를 불러오는데에 에러가 난 것이다.
해결방법1) build.gradle의 ProGuard 사용 부분 주석처리
하지만 이 에러 하나로 ProGuard를 사용하지 않는 것은 부자연스럽다고 생각했다.
해결방법2) 정적 클래스로 만들기
ProGuard를 사용해도 영향이 가지 않기 위해서 클래스를 정적 클래스로 만들었다.
static class TempItem {
...
}
수정한 결과 아무 문제없이 toOject() 메소드가 작동한다.
참고자료
앱 축소, 난독화 및 최적화 | Android 개발자 | Android Developers
What is proguard? | Android app development company (perfomatix.com)
[Android, Proguard] 안드로이드 프로가드 설정하기 (tistory.com)
공부하며 정리한 글입니다. 내용에 대한 피드백은 언제나 환영입니다.
'Error' 카테고리의 다른 글
[Error][PHP] Uncaught Error: Call to undefined function mysqli_connect() (0) | 2022.10.24 |
---|---|
[Error] AH00558: httpd: Could not reliably determine... (0) | 2022.10.24 |
[Error][VM] 우분투 네트워크 안됨 (0) | 2022.10.24 |
[Error][Git] main -> main (non-fast-forward) 오류 (0) | 2022.10.23 |
[Error][Android] Facebook log-in:Manifest merger failed (0) | 2022.10.23 |