본문 바로가기
개발 공부 기록하기/- Android

[Android] Unknown Source가 뜰때 해결하기

by soulduse 2017. 12. 9.


서론


개발하다가 에러가 나는데 어느 순간부터 크래시로 앱이 죽는데 


크래시의 내용이 상세하게 나오지 않는다.


별 대수롭지 않게 이건 시스템 내부쪽의 에러라서 표시가 안되는건가?? 하는 생각으로 


며칠을 버텼는데, 억지로 앱이 죽는에러를 발생시켜도 해당 라인이 문제라고 알려주지 않는것이 아닌가?


그러다가 공통적으로 뜨는 것이 Unknown Source라는 것을 알게 되었다.


아래와 같은 에러가 발생된다면 한번 두번 세번 의심해보자 나랑 같은 상황임을..


분명 NullPointException이 터졌는데 어디서 터졌는지는 안알랴줌으로 일관한다.



본론

짜증나는 나의 에러코드의 Unknown Source


UncaughtExceptionHandler

java.lang.NullPointerException

  at kr.socar.partner.view.activity.MainActivity$c.a(Unknown Source)

  at android.support.v4.view.ViewPager.e(Unknown Source)

  at android.support.v4.view.ViewPager.a(Unknown Source)

  at android.support.v4.view.ViewPager.a(Unknown Source)

  at android.support.v4.view.ViewPager.a(Unknown Source)

  at android.support.v4.view.ViewPager.setCurrentItem(Unknown Source)

  at kr.socar.partner.view.activity.MainActivity$a.a(Unknown Source)

  at android.support.design.widget.BottomNavigationView$1.a(Unknown Source)

  at android.support.v7.view.menu.h.a(Unknown Source)

  at android.support.v7.view.menu.j.b(Unknown Source)

  at android.support.v7.view.menu.h.a(Unknown Source)

  at android.support.design.internal.e$1.onClick(Unknown Source)

  at android.view.View.performClick(View.java:4630)

  at android.view.View$PerformClick.run(View.java:19339)

  at android.os.Handler.handleCallback(Handler.java:733)

  at android.os.Handler.dispatchMessage(Handler.java:95)

  at android.os.Looper.loop(Looper.java:157)

  at android.app.ActivityThread.main(ActivityThread.java:5335)

  at java.lang.reflect.Method.invokeNative(Native Method)

  at java.lang.reflect.Method.invoke(Method.java:515)

  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)



결론


build.gradle (app)

buildTypes {

release {

// 프로가드 활성화
minifyEnabled true


// 기본 프로가드 설정
proguardFile getDefaultProguardFile('proguard-android.txt')


// 프로젝트에서 필요한 프로가드 설정
proguardFile 'proguard-rules.pro'
}
}

proguard-rules.pro

keepattributes LineNumberTable, SoureFile

위와 같이 proguard-rules.pro에 keepattributes 키워드를 사용해서 SourceFile(소스 파일 정보), 

LineNumberTable(라인 넘버 정보)를 유지하도록 변경한 후 소스코드 에러가 어디서 났는지, 파일은 어디인지 잘 나온다!



부가설명

기본적으로 ProGuard를 설정하게 되면 가벼운 어플리케이션으로 변환하려고 노력을 하게된다. 

이과정에서  코드에서 실행하기 위해 꼭 필요하지 않은 모든 요소를 ​​제거하게 되는데, LineNumberTable과 SourceFile도 항목에 포함이된다.

따라서 라인넘버와 소스파일이 없기때문에 아무리 크래시가 발생되어 앱이 죽더라도 어디 라인에서 에러가 났는지, 에러난 소스파일이 

무엇인지 알수 없게 되는 것이다.

테스트를 해봤는데 (다해보진 않았지만) https://developer.android.com/reference/java/lang/StackTraceElement.html 

여기에 포함된 항목들은 ProGuard를 설정하면 지워져서 나오지 않는것 같다..


추가적으로 디버깅 모드일때만 소스파일과, 라인넘버를 유지하려면 아래와 같은 방식으로 설정하자.

buildTypes {

debug {
// 프로가드 활성화
minifyEnabled true

// 릴리즈 빌드에서 사용하는 프로가드 설정을 동일하게 추가합니다.
// 기본 프로가드 설정
proguardFile getDefaultProguardFile('proguard-android.txt')


// 프로젝트에서 필요한 프로가드 설정
proguardFile 'proguard-rules.pro'

// 디버그 빌드를 위한 프로가드 설정
proguardFile 'proguard-debug.pro'
}

release {
minifyEnabled true

// 기본 프로가드 설정
proguardFile getDefaultProguardFile('proguard-android.txt')


// 프로젝트에서 필요한 프로가드 설정
proguardFile 'proguard-rules.pro'
}
}

소스출처 : 갓커니님 블로그


proguard-debug.prokeepattributes LineNumberTable, SoureFile를 추가해주면 

디버그 상태일때는 라인넘버와 소스정보를 얻을수 있고, 릴리즈 일때는 모두 지워져서 앱이 한결 가벼워지고 난독화가 잘될 것이다.



오늘의 안드로이드 문제해결 끝!

반응형