Unity3D GCM java.lang.NoClassDefFoundError: com.test.gcm.R$drawable

 유니티3D 안드로이드에 외부 SDK 모듈 연동시에는 R.java와 관련된 이슈가 많네요. 아무래도 이클립스에서 다 관리해서 빌드하는게 아닌 유니티가 복사하고 조합해서 만드는 빌드 과정때문에 이런 이슈가 있는 것 같습니다. 이번에는 GCM 연동중 발생했는데 로그를 보시면,

FATAL EXCEPTION: IntentService[GCMIntentService-xxxxxxxxxxxx-1]
java.lang.Error: FATAL EXCEPTION [IntentService[GCMIntentService-150503376923-1]]
Unity version     : 4.1.2f1
Device model      : Acer A500
Device fingerprint: acer/a500_ww_cus1/picasso:4.0.3/IML74K/1336617649:user/release-keys
Caused by: java.lang.NoClassDefFoundError: com.test.gcm.R$drawable
at com.test.gcm.GCMIntentService.onMessage(GCMIntentService.java:49)
at com.google.android.gcm.GCMBaseIntentService.onHandleIntent(GCMBaseIntentService.java:223)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)

 이와 같습니다. 많이 보던 로그죠. 페이스북 연동할 때도 같은 에러가 발생했었습니다. layout이냐 drawable냐 차이죠.

Notification notification = new Notification();

notification.icon = R.drawable.ic_launcher;

 푸시가 오면 알림을 띄워줘야하는데 대략 소스는 위와 같습니다. 생각없이 코딩하고나서 에러때문에 확인해보니 에러가 날만하죠. 유니티3D로 안드로이드 Jar 플러그인 만들어 연동하는 부분에서 정리했듯이 유니티는 app_icon.png로 되어있기 때문인거죠.


해결책 1

app_icon cannot be resolved or is not a field GCMIntentService.java /com.test.gcm/src/com/test/gcm line 50 Java Problem

 그렇다고 무턱대고 자바소스에서 R.drawable.ic_launcher을 R.drawable.app_icon으로 바꾸면 당연하게도 위와 같은 에러가 발생하고 컴파일이 안되죠.

 이클립스가 프로젝트 만들때 자동으로 생성되는 리소스가 이 모양이니까요. 임시로 빌드를 하기 위해 이클립스의 R.java에 있는 ic_launcher을 app_icon으로 수정한 후 빌드했습니다. 어짜피 이클립스에서는 빌드해서 jar로만 생성되면 되니까요. 그렇게 해서 유니티 빌드 후 해봤지만 여전히 같은 문제로 안되더군요.

 간단히 해결하려면 자바 소스에서 notification.icon = 0x7f020000; 이렇게 직접 16진수 값을 입력해주면 되더군요. 이상하죠? R.java를 수정하던 직접 16진수로 입력하던 위 스샷과 같이 최종 유니티에서 사용하는 Temp\StagingArea 에 있는 R.java는 값이 같은데 말이죠. 유니티가 안드로이드 빌드하는 과정에 아직은 제가 모르는 부분이 있는 듯 합니다.

 아무튼 일단 잘 되지만 썩 맘에 들지 않는 해결책 1번이었습니다.


해결책 2

 일단 해결책 1 전 상황으로 다 돌아갔습니다. 즉, 이클립스는 R.java가 ic_launcher인 상태로 빌드가 되는거죠. 뭔가 R.java나 직접 16진수 상수값을 사용하지 않고 소스딴에서 리소스를 가져올 수 없을까 하고 구글링 해봤더니 있더군요.

Resources res = getResources();

notification.icon = res.getIdentifier("com.test.gcm:drawable/app_icon", null, null);

 이와 같이 스트링을 써서 가져올 수 있습니다. 첫인자에 몰아서 패키지명:리소스타입/리소스명 으로 하시거나

notification.icon = res.getIdentifier("app_icon", "drawable", "com.test.gcm");

 이렇게 나눠서 해줘도 되네요. 잘 작동합니다.

 유니티3D에 페이스북 안드로이드 연동시 나왔던 이슈도 이렇게 해결 가능할지는 나중에 해보고 정리를 해봐야겠습니다. 아무튼 전에도 언급했지만 유니티3D가 순수 게임 빌드는 한방에 되지만 역시나 외부 SDK 모듈이라도 들어가면 이슈가 자꾸 나오네요.

댓글

이 블로그의 인기 게시물

'xxx.exe' 프로그램을 시작할 수 없습니다. 지정된 파일을 찾을 수 없습니다.

goorm IDE에서 node.js 프로젝트로 Hello World Simple Server 만들어 띄워보기

애드센스 수익을 웨스턴 유니온으로 수표대신 현금으로 지급 받아보자.