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

FragmentPagerAdapter 를 사용하는데 종종 각 페이지의 Fragment 와 값 전달이 안됩니다.

0 추천

4개의 페이지로 구성된 간답한 앱을 만들었는데 처음 실행해서 기본적인 사용을 하는데는 전혀 문제가 없답니다.

단지 앱을 실행한 후 홈 화면으로 이동 하고 휴대폰을 끈다음 몇시간 지나서 다시 앱을 실행할 경우 백그라운드에 실행된 앱이 다시 포그라운드로 올라오는데 이때 MainActivity 에서 각각의 Fragment 로 값을 전달하면 먹통이 되더군요.

디버깅이 정말 힘든건 이 현상이 매번 일어나는게 아니라 백그라운드에 오랬동안 방치 했다가 실행할때 가끔식 생긴다는 거에요. 그리고 구형 폰에서는 오히려 이런 현상이 없는데 신형 겔럭시 폰에서는 자주 발생 하고요.

제 예상에는 백그라운드에 오래 방치된 앱의 경우 OS에 의해서 Fragment 라이프 사이클에 어떤 일이 발생 되는데 제가 이 부분을 잘 모르고 코딩하고 있는거라 예상됩니다.

기본적인 코드 구성은 아래와 같습니다. 문제가 되는 부분은 백그라운드에 오랫동안 있다가 포그라운드로 돌아왔을때 dataChange() 함수를 호출해도 각 Fragment 의 UI가 새로고침 되지 않는것 입니다. 평상시에는 전혀 문제 없이 작동 합니다. 백그라운드에 1시간 이상 방치 되었다가 포그라운드로 돌아 왔을때 50% 정도의 확율로 발생 됩니다.

아래와 같은 코드 구성은 근본적인 문제가 있는걸까요?

public class MainActivity extends AppCompatActivity {

     private TubeFragment mFragment0; 
     private TubeFragment mFragment1;
     private TubeFragment mFragment2;
     private TubeFragment mFragment3;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             
             mFragment0 = Fragment.newInstance();
             mFragment1 = Fragment.newInstance();
             mFragment2 = Fragment.newInstance();
             mFragment3 = Fragment.newInstance();             
     }

     private void dataChange() {
             mFragment0.change(data); 
             mFragment1.change(data); 
             mFragment2.change(data); 
             mFragment3.change(data); 
     }

     private class MyPagerAdapter extends FragmentPagerAdapter {
            MyPagerAdapter(FragmentManager fm) {
                    super(fm);
             }

             @Override
             public int getCount() {
                     return 4;
             }

             @Override
             public Fragment getItem(int position) {
                     switch (position) {
                           case 0: return mFragment0;
                           case 1: return mFragment1;
                           case 2: return mFragment2;
                           case 3: return mFragment3;
                     }
                     return null;
             }

             @Override
             public void destroyItem(ViewGroup container, int position, Object object) {
                    super.destroyItem(container, position, object);
             }
     }
}

 

Shock 님이 2018년 8월 16일 질문
혹시 오랫동안 방치후 다시 앱이 다시 포그라운드로 올라올때 해당 화면의 라이프사이클이 처음 부터 동작하나요 ?
메인에서 인스턴스를 쥐고 계시지 마시고 모델 클래스가 업데이트 될때마다 브로드캐스트를 날려주는 형식으로 변경하는게 나은것 같네요.
답변 감사합니다. 테스트해본 결과 브로드케스팅이 좀더 안정적 이군요.
아니오 기존에 있던 화면으로 복귀 하지만 데이터가 값이 적용되지 않아 있습니다.

1개의 답변

0 추천
Exception이 발생하지는 않고 단순히 Fragment.change();함수를 호출해도 동작하지 않는다는 말씀이시죠?
그러면 가장 먼저 각 메소드마다 로그를 찍어 잘 호출 되는지 확인해보시고, fragment의 모든 생명주기 메소드에 로그를 찍으셔야할 것 같아요. NullPointerException이 발생하지 않은것을 보면 각 변수들의 할당이 해제된것 같진않아보이네요.
백마귀족 (1,550 포인트) 님이 2018년 8월 23일 답변
로그를 찍어가면서 디버깅 하기는 좀 까깝한 상황 입니다. 위의 문제는 이미 설명한것 처럼 매번 발생되는게 아니라 실행된 앱이 1시간 또는 그 이상 백그라운드로 방치 시켰다가 포그라운르도 올렸을때 불규칙적으로 발생되는 오류니까요...
로그를 찍기 어려운 이유가 매번 발생되는것이 아니라 특정상황(장시간 백그라운드에 있다가 돌아온경우)이기 때문이라면 별 문제가 되지는 않습니다.
Fabric을 사용하여 특정 상황에 로그를 전송할 수도 있으니까요.
change()함수를 호출했을때 원하는 동작을 하지 않을 경우를 대비해
분기 처리 또는 exception처리를 하시고 Fabric에 로그를 남기시면서 디버깅하는 방법도 있습니다. 고려해보세요
답변 감사합니다. Fabric 을 적용해 봐야겠습니다.
...