마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

AVD와 갤7에선 되는데 노트10에서만 런타임 에러

0 추천

안녕하세요 어플리케이션을 테스트하고 있는데

AVD와 갤럭시7에서는 잘 구동이 되나, 갤노트10에서는 런타임 오류가 발생되어 질문드립니다.

*java.lang.RuntimeException: Unable to start activity ComponentInfo{kr.co.slowmotion.calendar/kr.co.slowmotion.calendar.MainActivity}: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment kr.co.slowmotion.calendar.Fragment1ScheduleDayList: could not find Fragment constructor

코드 상세 내용은 댓글에 첨부하겠습니다. 글자 수 초과로 기재가 안되네요..  

현재 계층 구조는

메인 액티비티 -> 프래그먼트 -> 프래그먼트(뷰페이저) 이며,

프래그먼트(뷰페이저)까지 화면에 그려진 뒤에 에러가 발생하는데 혹시 짚이시는 부분이 있을까요?

서한 (330 포인트) 님이 2021년 11월 16일 질문
서한님이 2021년 11월 16일 수정
혹시 에러가 나는 Fragment의 constructor을 올려보시겠어요?
class Fragment1Schedule(var startDay: Long?) : Fragment(), InterfaceForScrollView {
}
입니다
현재 위의 Fragment1Schedule은 FragmentFactory로 해결했는데

Fragment1Schedule의 뷰페이저에도 프래그먼트가 올라가는데
childFragment.FragmentFactory로 해결이 안되네요

class Fragment1ScheduleDayList(
    val minterface: InterfaceForScrollView,
    val date: Date
    ) : Fragment() {
}
로 되어있는 프래그먼트입니다.
죄송합니다. 추가적인 코멘트는
노트10에서 구동시,
액티비티의 onCreate에서 프래그먼트를 즉시 호출할 시, 에러가 발생하고
그렇지않고 버튼 클릭시에 프래그먼트를 호출하면 에러가 발생하지 않습니다
프레그먼트를 생성하는 방법이 잘못 되었습니다. 안드로이드에서는 프레그먼트의 경우 property가 없는 생성자를 사용하셔야 하고, 외부에서 전달한 필요가 있는 속성은 arguments를 통해 전달하셔야 합니다.
그래야 프레그먼트가 라이프사이클 때문에 재성성될 때 시스템이 전달된 속성을 복구시켜줄 수 있기 때문입니다. 그리고 필요하다면 FragmentFactory를 통해 프레그먼트 생성을 커스트마이징할 수 있습니다.
그리고 외부에서 property를   주입(injection)하는 패턴을 자주 사용하신다면 Dagger나 Hilt같은 Dependency Injection라이브러리를 사용하는게 정신건강에 좋을 거예요.
뷰페이저의 공통사용은 뷰페이저 관련 로직을 별도의 클래스 (일반 클래스 또는 커스텀 뷰)로 만드시고 이걸 프레그먼트 내에서 생성하세요. 그리고 Date같는 객체는 arguments를 통해 전달하시구요.
감사합니다 수정해보겠습니다
2021-11-16 16:37:13.219 23204-23204/kr.co.slowmotion.calendar E/AndroidRuntime: FATAL EXCEPTION: main
    Process: kr.co.slowmotion.calendar, PID: 23204
    java.lang.RuntimeException: Unable to start activity ComponentInfo{kr.co.slowmotion.calendar/kr.co.slowmotion.calendar.MainActivity}: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment kr.co.slowmotion.calendar.Fragment1ScheduleDayList: could not find Fragment constructor
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3835)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
        at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6047)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5942)
        at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:63)
        at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:6006)
        at android.app.ActivityThread.access$3500(ActivityThread.java:301)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2335)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8633)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
     Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment kr.co.slowmotion.calendar.Fragment1ScheduleDayList: 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.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:322)
        at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:273)
        at kr.co.slowmotion.calendar.MainActivity.onCreate(MainActivity.kt:38)
        at android.app.Activity.performCreate(Activity.java:8207)
        at android.app.Activity.performCreate(Activity.java:8191)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3808)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
        at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6047)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5942)
        at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:63)
        at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:6006)
        at android.app.ActivityThread.access$3500(ActivityThread.java:301)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2335)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8633)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
     Caused by: java.lang.NoSuchMethodException: kr.co.slowmotion.calendar.Fragment1ScheduleDayList.<init> []
        at java.lang.Class.getConstructor0(Class.java:2332)
        at java.lang.Class.getConstructor(Class.java:1728)
        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:322)
        at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:273)
        at kr.co.slowmotion.calendar.MainActivity.onCreate(MainActivity.kt:38)
        at android.app.Activity.performCreate(Activity.java:8207)
        at android.app.Activity.performCreate(Activity.java:8191)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3808)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
        at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6047)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5942)
        at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:63)
        at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:6006)
        at android.app.ActivityThread.access$3500(ActivityThread.java:301)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2335)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8633)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
FragmentFactory로 해결이 안된다면 디폴트 생성자를 사용하셔야 할 것 같은데요. 현재 에러가 안드로이드 시스템이 Fragment의 디폴트 생성자를 호출하려고 하는데, 디폴트 생성자가 없어서 나는 에러인데, FragmentFactory 사용했고 다른 디바이스에서 아무 이상이 없다면, 특정 디바이스만 SDK가 커스터마이징 된 최악의 상황을 고려해 볼 수 있습니다.

다시 보니까 뷰페이저 쪽이 의심스럽네요. 뷰페이져에서 프레그먼트를 사용하고 있다면, 뷰페이저는 FragmentFactory 처럼 커스텀 생성자를 호출할 수 없기 때문에, 디폴트 생성자를 제공해야 하겠죠.
저는 프로덕션에서 종류는 다르지만 SDK 가 커스터마이징 되어서 앱크래시가 난 경우를 만난 적이 있습니다.

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...