본문 바로가기
프로그래밍 놀이터/안드로이드, Java

Android Support Library 를 안정감 있게 사용하는 3가지 방법.

by 돼지왕 왕돼지 2014. 5. 16.
반응형


 Android Support Library 를 안정감 있게 사용하는 3가지 방법

 

출처 : http://www.crashlytics.com/blog/3-key-ways-to-increase-android-support-library-stability/

1. AsyncTasks and Configuration Changes


AsyncTask 를 실행시킨 fragment 가 asyntask 완료 되는 시점에서 activity 로부터 detach 되어있으면 다음과 같은 에러가 발생한다. AsyncTask 가 activity 로부터 detach 되어 있는 상황은 보통 configuration change ( 대표적으로 화면 전환 ) 의 경우에 주로 발생한다.


java.lang.IllegalStateException: Fragment MyFragment not attached to Activity

 at android.support.v4.app.Fragment.getResources(Fragment.java:551)

 at android.support.v4.app.Fragment.getString(Fragment.java:573)


이 에러를 막기 위한 한 방법으로는 AsyncTask 를 configuration change 에 대해 유지되도록 하는 것.


RetainedFragment 라는 class 를 이용하면 listener 를 통해 AsyncTask 의 상태를 listen 할 수 있다.

RetainedFragment 는 Build in class 가 아니고, thread 를 이용해서 config change 에 대해 destory 되지 않도록 하는 custom fragment 로 소스는 아래와 같다.


https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.java




2. Safely Performing Fragment Transactions.


Activity 가 fragment transaction 을 handle 할 수 없을 때 transaction 이 발생하면 다음과 같은 에러가 발생한다.


java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

 at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)

 at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager:1338)

 at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)

 at android.support.v4.app.BackStackRecord.commit(BackStackRecord:574)

 at android.support.v4.app.DialogFragment.show(DialogFragment:127)


FragmentActivity 가 background 가 되고, FragmentManigerImpl 의 mStateSaved flag 가 true 되었을 때 발생한다.

이 문제를 해결하기 위해서는 onSaveInstanceState() 가 불린 후에는 fragment transaction 이 수행되면 안 된다.

위와 같은 에러는 mStateSaved flag 가 false 로 바뀌기 전에 onResume 이 불릴 경우에 발생한다.

따라서 onResume() 에서의 fragment transaction 을 피하고, onResumeFragment() 에서 수행하는 것이 좋다.




3. Managing the Cursor Lifecycle.


CursorAdapter 를 쓰다 보면 다음과 같은 에러에 봉착하곤 한다.


java.lang.IllegalStateException: this should only be called when the cursor is valid

 at android.support.v4.widget.CursorAdapter.getView(CursorAdapter.java:245)

 at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:253)


이는 CursorAdapter 의 mDataValid 가 false 로 되었을 때 발생하며, 이는


1. cursor 가 null 일 경우

2. cursor의 requery 가 끝난 경우.

3. data 에 onInvalidated 가 호출된 경우.


위의 경우에 발생한다.


CursorLoader 와 startManagingCursor() 를 동시에 사용할 경우에 위의 경우가 주로 발생한다.


CursorLoader 가 생기면서 startManagingCursor 는 deprecated 되었다.

따라서 Fragment 와 CursorLoader 를 사용할 경우에는 startManaingCursor(), stopManagingCursor() 모두를 제거해주는 것이 좋다.






반응형

댓글