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

비동기 처리 시, Context부분에서 에러가 나는 것 같습니다 ㅜㅜ

0 추천

AsyncTask 비동기 처리 시, Context가 필요한 부분에서 nullPointerException이 계속 떨어지는데요.

제 감은 비동기 처리에서의 Context 처리 부분이 문제인데... 원인을 좀 알려주실 수 있나요...?

한번 에러난 이후로 재현이 잘 안되서 잡기가 어렵네요 ㅠㅠㅠ



private void getFirstData() {
        PrefUtil.getEditor(this).putString(Const.PREF_KEY_NOTICE_DATA, "").commit();
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                String result = NetworkUtil.connectGet(IntroActivity.this, API.getHomeUrl(PrefUtil.getPref(IntroActivity.this).getInt(Const.PREF_KEY_SELECTED_AGE_TYPE, 0)));
                Gson gson = new Gson()
                data = gson.fromJson(result, HomeResponse.class);

                // SharedPreferences에 객체 저장, IntroActivity.this 는 Context로 캐스팅 
                // 해당 구간에서 에러남 
                data.saveToLocal(IntroActivity.this);

                    result = NetworkUtil.connectGet(IntroActivity.this, API.FIRST_NOTICE_URL);
                    NoticeResponse response = new Gson().fromJson(result, NoticeResponse.class);
                    if (response != null && response.getCode() == 0)
                        PrefUtil.getEditor(IntroActivity.this).putString(Const.PREF_KEY_NOTICE_DATA, new Gson().toJson(response.getNotice())).commit();

                notiProcessDone();
            }
        });
    }

 

구구구구비둘기 (270 포인트) 님이 2017년 9월 26일 질문

1개의 답변

0 추천
AsyncTask에서는 Context에 직접 접근할 수 없습니다.

AsyncTask를 상속받는 클래스를 만드시고, 클래스의 constructor에 Context를 받으셔서

WeakReference<Context>를 들고 사용해야 합니다.

https://stackoverflow.com/questions/37531862/how-to-pass-context-in-async-task
minor (13,710 포인트) 님이 2017년 9월 26일 답변
전역 변수로 먼저 context를 이미 저장한 후, 비동기 처리를 해도 마찬가지 인가요?
네 Activity와는 LifeCycle이 다릅니다. AsyncTask의 Context로 지역변수를 선언해주셔야합니다.
일반적인 Context를 지역변수로 들고있으면 Memory leak이 발생할 수 있습니다.
WeakReference로 감싸서 들고 사용하시면 됩니다.
참고로 SharedPreference는 ApplicationContext로도 동작하기는 합니다 :)
아 그러면 저 IntroActivity.this 이 부분을 ApplicationContext로 대체해도 괜찮나요..?
구글측에서 추천하는 사용방식은 WeakReference이기는 합니다.
확신은 못하겠지만 되기는 할 것 같습니다.
아 그렇군요. 감사합니다. 혹시 구글 측에서 추천하는 방식이라고 하셨는데, api 문서에서 보신 건가요? 저도 왠만하면 문서대로 우선 개발해보려고요. 아직 초보 개발자라서요. ㅜㅜ
아 그렇군요. 감사합니다. 혹시 구글 측에서 추천하는 방식이라고 하셨는데, api 문서에서 보신 건가요? 저도 왠만하면 문서대로 우선 개발해보려고요. 아직 초보 개발자라서요. ㅜㅜ 그리고 이게 최초 앱 런치했을 때는 null 떨어지는데, 2회부터는 또 null이 안떨어지고 정상 작동하더라고요. 혹시 이유 좀 여쭤봐도 괜찮을까요?
더 나아가서 위와 같은 내용을 공부할 수 있는 자료 있으면 알려주시면 감사하겠습니다. ㅠ
WeakReference 개념을 처음 알게된게 API문서에서 알게된건 아니라서 API문서에도 있을지는 모르겠습니다. VM쪽 공부하면서 GC와 Reference 처리에 대해서 다룰 때 알게되었던 걸로 기억하고 있습니다.
최초 설치시에 Null이 발생하는건 항상 발생하는지 한번만 그런건지에 따라서 추측이 달라질 것 같습니다.
최초 설치시 한번만 Null인 현상은 내부 캐시정책때문인 것 같고, 지속적으로 발생하는 경우에는 LifeCycle이 맞지 않아서 context를 못찾는 걸 수 있습니다.
책 한권이나 문서 하나로 완벽하게 이해할 수 있는 개념은 아닌 것 같지만,
http://shop.oreilly.com/product/0636920029397.do
이 책이 thread와 asynctask, threadpool에 대해서 처음 배울 때 괜찮았었습니다.
http://d2.naver.com/helloworld/329631
한글 문서로는 이것도 깔끔하고 괜찮습니다.
와... 정말 감사합니다 ㅠㅠㅠㅠㅠㅠ UI 보다 Context가 훨씬 까다롭네요 ㅠㅠ
android는 UI thread나 메모리 정책이 특히 까다롭고 특이해서 고려해야할게 많습니다.
...