화면 가로 회전 시 앱 끊김 현상

개린이의 개발 노트·2023년 7월 21일
1

개발을 하다가 흥미로운 오류를 하나 발견했다.
휴대폰으로 테스트를 하다가 핸드폰을 살짝 기울였는데 가로 회전이 되면서 앱이 끊기는 것이었다.

황당해서 로그를 먼저 확인해 보았는데

FATAL EXCEPTION: main
Process: com.kuit.conet, PID: 11653
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kuit.conet/com.kuit.conet.MainBottomNavigation.KonetMainActivity}: androidx.fragment.app.FragmentInstantiationException:Unabletoinstantiatefragmentcom.kuit.conet.CalendarFragment:couldnotfindFragmentconstructoratandroid.app.ActivityThread.performLaunchActivity(ActivityThread.java:4111)atandroid.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4277)atandroid.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6429)atandroid.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6294)atandroid.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:71)atandroid.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)atandroid.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)atandroid.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)atandroid.app.ActivityThreadInstantiationException: Unable to instantiate fragment com.kuit.conet.CalendarFragment: could not find Fragment constructor at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4111) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4277) at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6429) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6294) at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:71) at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThreadH.handleMessage(ActivityThread.java:2443)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8751)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInitMethodAndArgsCaller.run(RuntimeInit.java:571)atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)Causedby:androidx.fragment.app.FragmentMethodAndArgsCaller.run(RuntimeInit.java:571) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) Caused by: androidx.fragment.app.FragmentInstantiationException: Unable to instantiate fragment com.kuit.conet.CalendarFragment: could not find Fragment constructor
at androidx.fragment.app.Fragment.instantiate(Fragment.java:628)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager3.instantiate(FragmentManager.java:483) at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85) at androidx.fragment.app.FragmentManager.restoreSaveState(FragmentManager.java:2728) at androidx.fragment.app.FragmentController.restoreSaveState(FragmentController.java:198) at androidx.fragment.app.FragmentActivity$2.onContextAvailable(FragmentActivity.java:149) at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.java:99) at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:362) at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:273) at com.kuit.conet.MainBottomNavigation.KonetMainActivity.onCreate(KonetMainActivity.kt:24) at android.app.Activity.performCreate(Activity.java:8290) at android.app.Activity.performCreate(Activity.java:8270) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4085) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4277)  at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6429)  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6294)  at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:71)  at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)  at android.app.ActivityThreadH.handleMessage(ActivityThread.java:2443) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loopOnce(Looper.java:226) 
at android.os.Looper.loop(Looper.java:313) 
at android.app.ActivityThread.main(ActivityThread.java:8751) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInitMethodAndArgsCaller.run(RuntimeInit.java:571)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)  Caused by: java.lang.NoSuchMethodException: com.kuit.conet.CalendarFragment.<init> [] at java.lang.Class.getConstructor0(Class.java:2363) at java.lang.Class.getConstructor(Class.java:1759) at androidx.fragment.app.Fragment.instantiate(Fragment.java:613) at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)  at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:483)  at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85)  at androidx.fragment.app.FragmentManager.restoreSaveState(FragmentManager.java:2728)  at androidx.fragment.app.FragmentController.restoreSaveState(FragmentController.java:198)  at androidx.fragment.app.FragmentActivity$2.onContextAvailable(FragmentActivity.java:149)  at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.java:99)  at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:362)  at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:273)  at com.kuit.conet.MainBottomNavigation.KonetMainActivity.onCreate(KonetMainActivity.kt:24)  at android.app.Activity.performCreate(Activity.java:8290)  at android.app.Activity.performCreate(Activity.java:8270)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4085)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4277)  at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6429)  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6294)  at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:71)  at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)  at android.app.ActivityThreadH.handleMessage(ActivityThread.java:2443) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loopOnce(Looper.java:226) 
at android.os.Looper.loop(Looper.java:313) 
at android.app.ActivityThread.main(ActivityThread.java:8751) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) 
2023-07-22 02:51:30.110 9683-14537 Finsky com.android.vending E [6277] VerifyV31SignatureInstallTask.d(34): VerifyApps V31SignatureVerification: Successful verification for the package: com.kuit.conet using APK Signature Scheme v3
2023-07-22 02:52:03.840 14772-14772 USNET pid-14772 E USNET: appName: com.kuit.conet

이런 듣도 보도 못한 오류들이 발생한 것이다.

사실 calendarView 프래그먼트 클래스에를 약속 목록, 대기 중 약속 목록과 같은 데이터들이 인자로 전달되게 구현을 하였는데 화면을 가로로 돌려서 oncreate가 자동으로 재호출되어서 인자들이 제대로 전달되지 못해서 오류가 나타난 것으로 보인다.

실제로 chatgpt에서도 인자가 없는 기본 생성자를 구현하라고 뜨던데 gpt가 준 코드를 사용해봐도 안된다. (오류가 나고 계속 이 상태로 질문했다가 코드가 더 기괴해지고, 길어질 것 같아서 pass...)

화면이 회전되었을 때 oncreate가 재호출 되지 않게 하는 방법도 있다고 하지만 activity가 복잡하면 이 방법도 안먹힌다길래 휴대폰을 돌려도 화면이 가로로 전환되지 않게끔 구현할 수 밖에 없었다.(아니면 calendarView를 뜯어고치던지 (데이터가 전달이 안되었을 때 예외처리 라던가, 전달인자가 없는 생성자를 선언을 하던가....)

방법은 간단했다. AndroidMenifest.xml파일에 들어가서 각 액티비티 태그 마다
android:screenOrientation="portrait" 구문을 추가해주면 끝이다.

반대로 화면을 가로고정하고 싶을 때에는
android:screenOrientation="landscape"구문을 추가해주면 된다고 한다.

내 핸드폰으로 빌드를 하니 가상기기에서 찾기 힘든 오류들을 발견할 수 있었던 것 같다.
실제 핸드폰으로 빌드를 하는게 빠르고, 숨은 오류를 찾기 수월한 것 같다.

참고 사이트
https://jhshjs.tistory.com/25

profile
개발 처음 시작함..... 그러니 잘못되거나 다소 이해안가는 코드들도 있을 수 있습니다 이점 양해 부탁드려요

0개의 댓글