Unity3D 91SDK 3.2.5 버전 초기화시 setContentView 문제

 중국 마켓 연동과 관련해서 서버와 실제로 작업을 하는 부분말고는 이제 작업이 없길 바랬는데 91마켓이 최신 SDK를 던져주면서 작업하지 않으면 게임 심의 통과 될 수 없는 상황이라며 일거리를 만들어주는군요.

 3.2.2에서 3.2.5로 업데이트 되면서 추가 처리해줘야 할 부분은 위와같습니다. 91SDK 3.2.5로 업데이트하면서 나온 이슈가 좀 길어서 위와 관련된 부분은 따로 정리를 해볼까합니다. 중간에 삽질 과정이므로 바로 해결책을 보실분은 마지막을 보시면 됩니다.

FATAL EXCEPTION: GLThread 5535
java.lang.Error: FATAL EXCEPTION [GLThread 5535]
Unity version     : 4.1.2f1
Device model      : Acer A500
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at com.nd.commplatform.gc.widget.LoadingBar$a.<init>(Unknown Source)
at com.nd.commplatform.gc.widget.LoadingBar$a.<init>(Unknown Source)
at com.nd.commplatform.gc.widget.LoadingBar.f(Unknown Source)
at com.nd.commplatform.gc.widget.LoadingBar.e(Unknown Source)
at com.nd.commplatform.gc.widget.LoadingBar.<init>(Unknown Source)
at com.nd.commplatform.d.c.gz.f(Unknown Source)
at com.nd.commplatform.d.c.gz.e(Unknown Source)
at com.nd.commplatform.d.c.gz.<init>(Unknown Source)
at com.nd.commplatform.d.c.b.a(Unknown Source)
at com.nd.commplatform.d.c.a.a(Unknown Source)
at com.nd.commplatform.NdCommplatform.ndInit(Unknown Source)
at com.wwforever.plugin91.MainActivity.init91SDK_U(MainActivity.java:71)
at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
at com.unity3d.player.UnityPlayer.onDrawFrame(Unknown Source)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1216)
  Force finishing activity com.wwforever.plugin91/.MainActivity
Activity pause timeout for ActivityRecord{417cf390 com.wwforever.plugin91/.MainActivity}

 업데이트된 91 SDK init를 해주면 기존에 안나던 에러가 발생합니다. 하지만 기존에 많이 봐왔던 GLThread 에러니 간단히 해결합니다. 문제는 이게 아니고,

 바로 이게 문제입니다. 업데이트 되면서 초기화할 때 자체 91마켓 UI를 뿌려주더군요. 그덕에 위와 같이 GLThread 에러도 발생했던거고요. 그런데 이 UI가 사라지질 않는 이슈가 발생한 것이죠.

91SDK version(6244): 3.2.5.2
connect by wifi
success
connect by wifi
connect by wifi
connect by wifi
connect by wifi
NdExitConfigPage[mADList=[], mLastModified=2013-07-23 17:34:43, mRank=[NdExitRankEntry[mAdType=1, mPageRank=15], NdExitRankEntry[mAdType=2, mPageRank=15], NdExitRankEntry[mAdType=3, mPageRank=0]]]
NdStartConfigPage[mADList=[], mActivityADList[], mAdLastModified=2013-05-23 18:56:50, mActivityAdLastModified2013-04-25 18:10:14]
NdPauseConfigPage[mADList=[], mLastModified=2013-06-19 16:17:50, mRank=[NdPauseRankEntry[mAdType=1, mPageRank=40], NdPauseRankEntry[mAdType=2, mPageRank=30], NdPauseRankEntry[mAdType=3, mPageRank=1], NdPauseRankEntry[mAdType=4, mPageRank=29]]]
ndInit onComplete

 위와 같은 로그만 남긴채 말이죠. 초기화 완료되었다는 콜백까지 왔는데도 창이 그대로 있고 백버튼을 눌러도 유니티3D 화면으로 돌아가지 않더군요.

this.setContentView(R.layout.welcome);

 91마켓 SDK의 ND_Demo를 확인해보니 SDK 초기화 후 오는 콜백에서 위와같이 setContentView를 해주더군요. 데모에서 저부분을 주석하고 빌드 후 테스트하니 데모도 같은 증상이더라구요. 원인은 파악되었지만 유니티3D에서는 setContentView를 해주면 안되기 때문에 다른 방법을 알아봤습니다.


View unityView = getWindow().getDecorView().getRootView();
setContentView(unityView);

 첨에는 삼성 개발자 센터에서 유니티앱에 S펜 SDK 연동 방법 글을 보고 위와같이 해줬으나,

FATAL EXCEPTION: main
java.lang.Error: FATAL EXCEPTION [main]
Unity version     : 4.1.2f1
Device model      : Acer A500
Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:3337)
at android.view.ViewGroup.addView(ViewGroup.java:3208)
at android.view.ViewGroup.addView(ViewGroup.java:3188)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:274)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:264)
at android.app.Activity.setContentView(Activity.java:1855)
at com.wwforever.plugin91.MainActivity.initActivity(MainActivity.java:49)
at com.wwforever.plugin91.MainActivity.access$0(MainActivity.java:41)
at com.wwforever.plugin91.MainActivity$1$1.onComplete(MainActivity.java:82)
at com.nd.commplatform.OnInitCompleteListener.finishInitProcess(Unknown Source)
at com.nd.commplatform.d.c.b$2.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
  Force finishing activity com.wwforever.plugin91/.MainActivity
Activity pause timeout for ActivityRecord{410ff1a0 com.wwforever.plugin91/.MainActivity}

 차일드뷰가 이미 있으니 remove먼저하고 하라는 에러가 발생하더군요. 관련해서 ViewGroup를 얻어와서 추가로 처리해봤지만 다른에러만 발생했습니다.

 두번째로 유니티 해외 포럼에 안드로이드 추가 서브 뷰를 사용하는 방법이 있더군요. 괜찮은 방법같지만 그냥 패스했습니다. 그냥 91마켓 초기화용 액티비티를 만드는게 더 빠르다고 판단했거든요.

res\layout\activity_main.xml:1: error: Error: No resource found that matches the given name (at 'paddingBottom' with value '@dimen/activity_vertical_margin').
res\layout\activity_main.xml:1: error: Error: No resource found that matches the given name (at 'paddingLeft' with value '@dimen/activity_horizontal_margin').
res\layout\activity_main.xml:1: error: Error: No resource found that matches the given name (at 'paddingRight' with value '@dimen/activity_horizontal_margin').
res\layout\activity_main.xml:1: error: Error: No resource found that matches the given name (at 'paddingTop' with value '@dimen/activity_vertical_margin').
res\layout\activity_main.xml:11: error: Error: No resource found that matches the given name (at 'text' with value '@string/hello_world').

Error building Player: UnityException: Resource re-package failed!
Failed to re-package resources. See the Console for details.

 그냥 액티비티를 추가해서 startActivity로 호출해서 처리하자 하는데 위와같은 에러가 발생했습니다. 기존에 발생하던 Resource re-package failed와는 다른거죠. 액티비티를 만나들면서 프로젝트를 만들때 자동으로 만들어진 res/layout/activity_main.xml 파일을 유니티3D폴더에 넣었다가 생긴 에러였는데

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

 위와 같은 기본적인 내용에서 에러가 났던 필요없는 내용을 제거하고

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
</RelativeLayout>

 이렇게 해주면 에러는 발생하지 않더군요. 이제 실행해보면,

FATAL EXCEPTION: main
java.lang.Error: FATAL EXCEPTION [main]
Unity version     : 4.1.2f1
Device model      : Acer A500
Caused by: java.lang.NoClassDefFoundError: com.wwforever.plugin91.R$layout
at com.wwforever.plugin91.New91SDKActivity.onCreate(New91SDKActivity.java:21)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
  Force finishing activity com.wwforever.plugin91/.New91SDKActivity
  Force finishing activity com.wwforever.plugin91/.MainActivity
Activity pause timeout for ActivityRecord{4158baf8 com.wwforever.plugin91/.New91SDKActivity}

 에러가 발생합니다.

public class New91SDKActivity extends Activity {
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  //setContentView(R.layout.activity_main);
  
  init91SDK();
 }
 
 private void init91SDK() {
           //기존 91 초기화 내용...
        }
}

 위와같이 New91SDKActivity라고 액티비티를 작업한 상태였는데 UnityPlayerActivity를 상속받지 않는데도 setContentView가 하지 않아야 에러가 발생하지 않더군요. 그래서 activity_main.xml도 필요없구요.

 발생한 이슈 정리한다고 내용이 길어졌지만 결론은 인텐트를 만들어서 startActivity로 잠시 91마켓 초기화용 액티비티를 처리하면 됩니다.

 private void init91SDK_U() {
  Intent intent = new Intent(this, New91SDKActivity.class);
  startActivity(intent);
 }
 기존 MainActivity에서 유니티3D로부터 초기화 호출되면 이렇게 새로만든 액티비티를 호출하면 되는거죠.

<activity android:name="com.wwforever.pluginchina91.New91SDKActivity" />

 AndroidManifest.xml에 위와같이 액티비티 추가도 잊지 마시기 바랍니다.

이 블로그의 인기 게시물

CMake Windows에 설치하기

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

Unity3D 안드로이드 Keystore 생성하기