Android

[Fragment] Activity 에서 Fragment 호출 유의점 (Unable to instantiate fragment)

Dean83 2023. 1. 13. 11:15

Activity 에서 Fragment를 호출할때 인자값을 넘겨줘야 할 때가 있다. 

왠만한 변수들은 put을 이용해 넘겨줄 수 있다. 

 

그러나 data class 가 아닌, activity에 연결된 클래스 등을 넘겨줘야 할때도 있는데, 이 때는 put으로 넘겨주기가 힘들다.

또한 ArrayList 등을 넘길 때에도 Parcel을 이용하느냐, Serializable을 이용하느냐의 차이도 있는데, Serializable로 data class를 설정했을 경우에는 put으로 넘길때 오류가 생긴다. 

 

이럴경우 보통 Fragment 생성자에 인자값을 넣어서 넘기는게 편하기 때문에 이렇게 구현하는 경우가 꽤 있었다. 

 

문제는, activity가 재생성될때 - 가로모드에서 세로모드로 변경 등 - fragment 또한 재생성이 되는데, fragment 생성자에

인자값이 들어가 있는 경우 Unable to instantiate fragment 오류가 난다는 점이다. 
=> SavedBundle 쪽에서 처리를 해주지 못한다. 

=> Fragment 측에서 detach 될때 등 수동으로 bundle 저장하는것도 여간 번거로운게 아니고, 위에 언급한 형태의 변수들은 저장도 안된다. (혹은 까다롭다)

 

Fragment 생성자에는 인자값이 아무것도 없는 () 형태로 구성이 되어야 한다.

 

그러면, Activity에 연관되어 있는 클래스(ViewModel 이라든지) 의 특정 함수를 호출해야 한다든지 할경우에는
어떻게 해야 할까?

Fragment는 Activity에서 호출하므로 this.RequiredActivity()를 이용하면 Activity에 접근할 수 있고, ViewModel 등에도 접근할 수 있다.

 

ViewModel은 Activity와 다르게 라이프사이클이 길기 때문에, ViewModel에 필요한 변수들을 저장하여 연계해서 사용하는것도 방법이다.  

 

 

========= 단순 스트링을 인자값으로 넘기는 방법 =============

 

Fragment 생성시, (예 : Activity 에서) 

var fragment = Fragment클래스명()
var bundle  = Bundle()
bundle.putString("키값",밸류값)
fragment.arguments = bundle

 

Fragment 생성자에서,

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

         if(requireArguments()!= null && requireArguments().getString("키값").isNullOrEmpty() == false)
            멤버변수명 = requireArguments().getString("키값")!!
    
    }

 

관련 링크 : https://stackoverflow.com/questions/7016632/unable-to-instantiate-fragment