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

Fragment 사용시 getActivity() 가 null로 오는경우

0 추천

fragment사용시 Toast등을 사용하기 위해 getActivity()를

사용해야 합니다.

앱을 디버깅하고 실행하면 처음에는 잘 됩니다.

그런데 애플리케이션이 죽었다 다시 살아나는 경우 (정확히 캐쉬만 날라간 경우)

getActivity()가 특정 조건에서 null로 떨어지게 됩니다.

 

public class Test extends Fragment {

    @Override
    public View onCreateView(...생략) {
        View rootView = inflater.inflate(생략);
        loadWeb();
        return rootView
    }

    public loadWeb() {
        getActivity() // 이 부분은 null이 아님
        
        connector = new Connector();
        connector.setNetworkListener(new NetworkListener() {
            
            @Override
            public void onSuccess() {
                getActivity() // 이 부분은 null
            }
        }

        getActivity() // 이 부분은 null이 아님
    }
}

 

특이한 경우가 스레드를 사용하는 인터페이스 안에 getActivity()는 null로 떨어지게 되지만

함수안에 있는 경우는 잘 받아온 다는 점입니다.

이 것도 신기하지만 더 신기한것도 있습니다.

 

onSuccess() 인터페이스 함수를 다음과 같이 한 번 null인지 검증을 하면 null이 아니게 됩니다.

@Override

public void onSuccess() {

    getActivity() => 널

    if (getActivity != null) {

        getActivity() => 널 아님

    }

}

 

현재 해결책은 onStart() 안에서 앱 동작에 관한 것을 구현하고 있습니다.

이 때는 getActivity()가 널로 내려오지 않더군요.

 

스레드 생명 주기는 보니, 앱 캐쉬가 날라가면

onAttach 를 불렀다가 다시 detach를 부르고 다시 onAttach를 부른다는 점입니다.

 

혹시 이런 경험 하신 분들...조언좀 부탁드려요

밥아저씨 (200 포인트) 님이 2013년 10월 6일 질문

1개의 답변

0 추천
Fragment 의 생명주기 콜백 함수 이름들을 보면 다음과 같습니다.

onAttach() -> onCreated -> onCreateView() -> onActivityCreated() -> onStart() -> onResume()

이름에서 보시듯, onCreateView() 이후에 onActivityCreated() 가 호출되므로, onCreateView 시점에서는 Activity 생성을 보장할수 없습니다. 자세한건 Fragment 의 소스를 열어보시면 확실합니다.
상인 (6,670 포인트) 님이 2013년 10월 6일 답변
상인님이 2013년 10월 6일 수정
감사합니다.

그런데 onCreateView() 에서 함수를 호출해봐도
인터페이스 안에 있는 getActivity()만 null로 가져오는군요.
지금보니 캐쉬를 날리면 activity cycle이

onAttach -> onCreateView -> onActivityCreated -> onDetach -> onAttach -> onCreateView ......(생략) 요렇게 중간에 한 번 onDetach를 부르네요.
그 때문에 이 전의 getActivity()가 널로 내려오는것 같습니다.
예 그래서 위에 올리신 예제의 onSuccess 의 경우 Fragment 생명주기랑 관계 없어서 있을수도 있고 없을수도 있는 경우가 발생할것 같습니다.

Fragment 가 View의 집합을 관리하는 확장 정도라서 그냥 맞춰써야죠. 저도 조심조심 씁니다. ;;
...