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

Fragment 에서 getAcitivy나 getContext를 안전하게 사용 할 수 있는 방법이 있을까요?

0 추천
안녕하세요.

혼자 찾아보다 해결을 못해서 질문 올려봅니다.

 

제가 Fragment에서 getContext( 혹은 getActivity)를 이용해 getPackageName() 호출해서 사용하는 구간이 있습니다.

기본 작동에서는 잘 작동되고 문제가 없는데 해당 Fragment에서 다른 액티비티 화면으로 넘거갔다

돌아오면 null 반환으로 더이상 사용이 안되는 문제가 발생했습니다.

 

여러 포럼도 찾아보고 하니 별도의 클래스를 만들어 정의하고 그걸 필요한 곳에서  반환받아

사용하라는 내용들이 많더라고요.. 그런데 그와 함께 메모리 누수에 관한 부정적이고 그걸 해결하기

위한 내용들이 많던데.. 저는 적용시켜봐도 변함없는 에러만 내뿜고 있습니다.

 

isAdded 방법도 나와서 살펴보니 이건 null 에러를 피하는거지 제가 생각하는 재사용을 위한

목적이 아니더라고요..

 

이걸 해결하기 위해서 제가 찾아봐야하는 부분이 무엇인지 힌트좀 부탁드려요
nickeun (540 포인트) 님이 2018년 4월 28일 질문
nickeun님이 2018년 4월 28일 수정

1개의 답변

0 추천
public class MyContext {
    private static MyContext INSTANCE;
    private Context mContext;

    private MyContext(Context _context){
        mContext = _context;
    }

    public static MyContext getINSTANCE(Context _context) {
        if(INSTANCE == null){
            INSTANCE = new MyContext(_context.getApplicationContext());
        }
        return INSTANCE;
    }

    public Context getmContext() {
        return mContext;
    }
}

이렇게 별도로 구성하여 필요한 곳에서 호출하여 사용하니 잘 작동하네요.

제 수준에서 찾은 방법으로는 지금은 이정도가 최선인거 같네요 ^^ 

혹시 더 알아야할 내용이 있다면 다양한 댓글 부탁드립니다.

nickeun (540 포인트) 님이 2018년 4월 28일 답변
해결이 되지 않아 다시 올립니다.

해당 클래스를 만들어놓고

여러곳에 사용되지만 UI 출력 되는 부분만 올려 보겠습니다.

public void onAttach(Context context) {
        super.onAttach(context);
        myContext = MyContext.getINSTANCE(context);
    }

int resId = myContext.getmContext().getResources()
.getIdentifier("@drawable/default_image","drawable"
, myContext.getmContext().getPackageName());

이제는 필요 정보도 호출은 잘 됩니다.

                Glide.with(myContext.getmContext())
                        .load(resId)
                        .apply(options.circleCrop())
                        .into(users);

context가 필요한 부분에 (myContext.getmContext()) 이렇게 호출하여 사용해보려 했습니다.

처음에는 잘 작동되나 다른 액티비티에 갔다 돌아오면 더이상 레이아웃 정보가
갱신되지 않습니다. ㅠ... 산 넘어 산이네요..

null  에러는 피한거 같은데 정확한 방법은 아녔던건가요? ㅠ
저는 이런식으로 사용합니다.
public class MyApp extends Application {
  private static MyApp instance;

  public static Context getContext() {
    return instance;
  }

  @Override
  public void onCreate() {
    instance = this;
    super.onCreate();
}
}

이렇게 하시고
Glide.with(MyApp.getContext()) 하시면 될것 같아요
프래그먼트의 라이프사이클에 따라서 myContext가 사라진것 아닌가요?
저는 왜 그렇게 적용시키면 .getPackageName() 부분이 null 참조가 될까요?
아.. 댓글 달아주신 부분을 적용하면 해당 저 위치가 처음부터 에러가 납니다.

분명 잘 쓰고 계시는 코드라 하셨는데 ㅠㅠ 제가 분명 뭘 잘못하긴 했나봐요;;;ㅠ

제대로 작성한건지도 모른는 제 코드로는 해당 부분에서는 null 참조는 이뤄지지
않고 Log를 찍어보면 정상적으로 데이터를 가져오거든요.

문제는 다른 액티비티로 다녀오면서 라이프사이클에 따라 삭제 됐다가
재사용이 되면서 UI출력 부분이 먹통이 되어서요 ㅠ

페이지간 이동에서도 Fragment가 삭제되고 재사용되면서 같은 현상이 일어나더라고요.
setOffscreenPageLimit(??) 사용해서 강제적으로 지워지지않게 범위를 지정하면
피할수는 있지만 여전히 다른 액티비티를 넘어갔다오면 문제가 되네요

데이터 처리 과정에선 문제가 없어 작동되나 UI부분이 문제인가 싶어 강제적으로
TextView에다 직접 입력을 대입시켜보니 그거 조차도 표시되지 않더라고요.
제가 어디서 부터 잘못된건지 감을 전혀 못잡고 있네요.
TextView static 선언 되지 않은게 문제였네요
직접 입력되지 않았다는건  실행 위치가 잘못되었던거였네요;;;
혹시 저와 같은 실수로 검색하시는 분들이 계실가 남겨 놓습니다.

프래그먼트에서 사용되는 Context는 별도의 클래스 사용해야할거 같네요.
문제되는 부분을 피하긴 한거 같은데.. 이게 맞는건가 싶긴 합니다.
...