시리즈

7.1: AsyncTask and AsyncTaskLoader (2 AsyncTaskLoader)

20171127
android
daily

원글: https://google-developer-training.gitbooks.io/android-developer-fundamentals-course-concepts/content/en/Unit%203/71c_asynctask_and_asynctaskloader_md.html
(Android Developer Fundamentals Course (concepts) 7.1)

Contents:

Loaders

백그라운드 작업은 보통 데이터(예측보고서, 영화 리뷰 등) 를 불러올 때 사용한다. 데이터를 불러올때는 메모리가 많이 필요하다. 그리고, 디바이스 설정이 바뀌든 말든 데이터를 불러와야만 한다.
이러한 경우 loader를 이용한다. loader는 액티비티에서 데이터를 불러오는 것을 도와주는 클래스 집합이다.
Loader는 LoaderManager 클래스를 1개 이상의 loader들을 관리하기 위해 사용한다. LoaderManager는 loader가 만들어질때, 데이터 로드가 완료될때, 그것이 리셋될때를 나타내는  콜백의 집합을 포함한다.

loader를 시작하기

한 액티비티나 프래그먼트에 들어있는 Loader 인스턴스들을 관리하기 위해서 LoaderManager를 사용한다. initLoader()를 사용해서 loader를 초기화하고 작동하게 할 수 있다. 보통, 액티비티의 onCreate() 메소드에서 하게 된다.
예시:
// Prepare the loader.  Either reconnect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
지원 라이브러리를 사용한다면, getSupportLoaderManager() 를 getLoaderManager() 대신 사용할 수 있다. 
예시: 
getSupportLoaderManager().initLoader(0, null, this);
initLoader() 메소드는 3개의 매개변수를 가진다.
  1. loader를 나타낼 고유 ID
  2. loader를 만들 때 선택 매개변수 (번들), 이미 loader가 존재한다면 이 매개변수는 무시된다.
  3. loader 이벤트들을 보고하기 위해 LoaderManager를 호출하는 LoaderCallbacks 을 구현. 예를 들어, 로컬 클래스는 LoaderManager.LoaderCallbacks 인터페이스를 구현하고 그것의 레퍼런스를 전달한다 (this)
initLoader() 호출은 2개의 리턴값을 가질 수 있다.

  • loader가 이미 존재하는 ID를 가진다면, 그 ID로 만든 마지막 loader가 재사용된다.
  • loader가 새로운 ID를 갖는다면, initLoader()는 onCreateLoader() 메소드를 트리거한다. 이 메소드는 인스턴스화 하고 새로운 로더를 리턴하는 코드를 구현하는 곳이다.

loader 재시작하기

이미 있는 loader를 initLoader()로 재사용 할 경우, loader가 가지고 있던 데이터는 그대로 남아있다. 하지만 가끔은 데이터를 바꿔야 할 때도 있을 것이다. 예를 들어, 검색을 할 때 유저가 새로운 쿼리를 입력하면 새로운 검색 결과를 이용해서 데이터를 바꿔야한다. 이 경우 restartLoader() 메소드를 이용해서 재시작하고자 하는 loader의 ID를 전달하면 된다. 이 메소드는 새로운 입력 데이터를 이용해서 데이터를 로드하도록 한다.
restartLoader() 메소드 특징:
  • restartLoader() 는 initLoader()와 같은 매개변수를 가진다. 
  • restartLoader() 는 onCreateLoader() 메소드를 트리거 한다. initLoader() 에서 하는 방식과 같다.
  • 주어진 ID를 가진 loader가 이미 존재하면, restartLoader()는 그 loader를 재시작하고 데이터를 교체한다. 
  • 주어진 ID를 가진 loader가 없으면, restartLoader() 새로운 loader를 시작한다.

LoaderManager callbacks

The LoaderManager 객체는 loader를 만들때 onStartLoading() 메소드를 자동으로 호출한다. 그러고 나서 LoaderManager는 액티비티의 상태와 데이터를 기반으로 loader의 상태를 관리한다. 데이터가 로드되면 onLoadFinished() 호출하는 식으로.

loader와 상호작용을 하기 위해서 액티비티에서 LoaderManager callbacks 를 사용해야 한다.


  • onCreateLoader() 는  주어진 ID로 된 새로운 loader를 인스턴스화하고 반환한다.
  • onLoadFinished() 는 이전에 만들어진 loader가 로딩이 완료되면 호출한다. 주로 액티비티 뷰 안으로 데이터가 이동했을때 이다.
  • onLoaderReset() 는 이전에 만들어진 loader가 리셋됐을 때 호출된다. 이것은 loader의 데이터를 사용할 수 없도록 만든다. 이 시점에서 앱은 loader의 데이터를 가진 모든 레퍼런스를 제거해야한다.
Loader의 서브클래스는 데이터를 실제로 로드해야 할 의무가 있다.
로딩할 데이터의 유형에 따라 Loader의 서브클래스를 결정해야 하지만 대부분의 경우에 AsyncTaskLoader를 사용한다. AsyncTaskLoader는 워커 쓰레드에서 작업을 수행하기 위해AsyncTask를 사용한다.

AsyncTaskLoader

AsyncTaskLoader 는 AsyncTask에 상응하는 loader이다. AsyncTaskLoader는 loadInBackground() 메소드를 제공한다. loadInBackground() 메소드는 개별 스레드에서 작동한다. loadInBackground()의 결과는 자동으로 onLoadFinished() LoaderManager 콜백을 이용해서 UI 스레드로 전달된다. 
AsyncTaskLoader 용법
AsyncTaskLoader의 서브클래스를 정의하기 위해서 AsyncTaskLoader<D>를 확장하는 클래스를 만들어야한다. D는 로드할 데이터의 타입이 된다.
string의 List를 로드하는 AsyncTask의 경우, 
public static class StringListLoader extends AsyncTaskLoader<List<String>> {}
다음은 슈퍼클래스의 구현과 일치하는 생성자를 구현해야 한다.

  • 생성자는 app context를 인수로 받아 super() 호출에 전달한다. 
  • loader가 로드를 수행하기 위해서 추가적인 정보를 원한다면, 생성자는 부가적인 인수를 가질 수 있다. 아래의 예시를 참조하자.
public StringListLoader(Context context, String queryString) {
   super(context);
   mQueryString = queryString;
}

로드를 수행하기 위해서, loadInBackground() 오버라이드 메소드를 사용하자. AsyncTask의 doInBackground() 로 귀결된다.


@Override
public List<String> loadInBackground() {
    List<String> data = new ArrayList<String>;
    //TODO: Load the data from the network or from a database
    return data;
}

콜백 구현하기

새로운 loader가 만들어지는 onCreateLoader() LoaderManager 콜백에서 생성자를 사용한다.
예를 들어, 이 onCreateLoader() 콜백은 위에서 정의한 StringListLoader 생성자를 이용한다. 
@Override
public Loader<List<String>> onCreateLoader(int id, Bundle args) {
   return new StringListLoader(this, args.getString("queryString"));
}
loadInBackground()의 결과는 onLoaderFinished() 콜백으로 전달된다. onLoaderFinished 콜백에서 UI로 결과를 보여주게 된다.
public void onLoadFinished(Loader<List<String>> loader, List<String> data) {
    mAdapter.setData(data);
}
onLoaderReset() 콜백은 loader가 파괴되면 호출된다. loader가 파괴되고 나면 데이터에 접근할 필요가 없기 때문에 onLoaderReset() 을 대부분의 경우에 공백으로 남겨 둘 수 있다. 
+

AsyncTaskLoader 를 사용할 때, 데이터는 장치-설정이 바뀌어도 그대로 남아있게 된다. 만약 액티비티가 완전히 파괴되면 로더도 함께 파괴되고 더 이상 시스템의 리소스를 소비하지 않는다.
Loaders 는 그 밖의 장점들도 가지고 있다. 변화하는 데이터 소스를 볼 수 있게 하고, 데이터가 바뀌면 데이터를 리로드해준다.

.

piano (press key Q)

Categories

flutter ( 82 ) dart ( 34 ) android ( 32 ) kotlin ( 11 ) plugin ( 8 ) provider ( 8 ) vim ( 7 ) bloc ( 6 ) iOS ( 6 ) state management ( 6 ) 플러터 ( 6 ) PS ( 5 ) algorithm ( 5 ) architecture ( 5 ) async ( 5 ) getx ( 5 ) java ( 5 ) API ( 4 ) BOJ ( 4 ) class ( 4 ) daily ( 4 ) git ( 4 ) golang ( 4 ) memo ( 4 ) riverpod ( 4 ) state ( 4 ) stream ( 4 ) test ( 4 ) web ( 4 ) widget ( 4 ) windows ( 4 ) HTTP ( 3 ) androidX ( 3 ) app state ( 3 ) context ( 3 ) crash ( 3 ) db ( 3 ) editor ( 3 ) error ( 3 ) extension ( 3 ) github ( 3 ) hive ( 3 ) ide ( 3 ) package ( 3 ) pubspec ( 3 ) python ( 3 ) syntax ( 3 ) vscode ( 3 ) app icon ( 2 ) await ( 2 ) chocolatey ( 2 ) consumer ( 2 ) cp949 ( 2 ) deployment ( 2 ) dev ( 2 ) flavor ( 2 ) gesture ( 2 ) globalkey ( 2 ) go ( 2 ) google ( 2 ) hack ( 2 ) js ( 2 ) json ( 2 ) key ( 2 ) keystore ( 2 ) list ( 2 ) listview ( 2 ) lock ( 2 ) mac ( 2 ) map ( 2 ) navigation ( 2 ) nosql ( 2 ) project ( 2 ) pub ( 2 ) recyclerview ( 2 ) rxdart ( 2 ) sdk ( 2 ) selector ( 2 ) setting ( 2 ) size ( 2 ) soc ( 2 ) synchronized ( 2 ) tdd ( 2 ) tip ( 2 ) version ( 2 ) viewmodel ( 2 ) vundle ( 2 ) webview ( 2 ) xcode ( 2 ) yaml ( 2 ) ( 2 ) 플러터 단점 ( 2 ) 16.0 ( 1 ) 2.0 ( 1 ) 2023 ( 1 ) AATP2 ( 1 ) ChangeNotifierProvider ( 1 ) Example ( 1 ) Guava ( 1 ) ImageReader ( 1 ) Mo's algorithm ( 1 ) OAuth2 ( 1 ) OpenGL ( 1 ) Oreo ( 1 ) ProgressBar ( 1 ) REST API ( 1 ) Trie ( 1 ) activity ( 1 ) adaptive ( 1 ) android P ( 1 ) android context ( 1 ) android11 ( 1 ) apktool2 ( 1 ) app exit ( 1 ) append ( 1 ) appicon ( 1 ) arkit ( 1 ) array ( 1 ) asciidoc ( 1 ) async * ( 1 ) async* ( 1 ) audio ( 1 ) authorization ( 1 ) await for ( 1 ) behaviorsubject ( 1 ) beta ( 1 ) binary ( 1 ) binarysearch ( 1 ) blender ( 1 ) book ( 1 ) bottomsheet ( 1 ) break ( 1 ) broadcast ( 1 ) browser ( 1 ) bubbles ( 1 ) bug ( 1 ) build ( 1 ) buildcontext ( 1 ) buildnumber ( 1 ) bundle ( 1 ) button ( 1 ) bytecode ( 1 ) cache ( 1 ) camera2 ( 1 ) cameramanager ( 1 ) cd ( 1 ) chrome ( 1 ) ci ( 1 ) circle ( 1 ) clean ( 1 ) clean architecture ( 1 ) cli ( 1 ) clip ( 1 ) clipboard ( 1 ) cloud ide ( 1 ) cmdlet ( 1 ) code ( 1 ) coding test ( 1 ) command ( 1 ) comparator ( 1 ) complexity ( 1 ) concurrency ( 1 ) conditional ( 1 ) const ( 1 ) constraint ( 1 ) constraintlayout ( 1 ) controlc ( 1 ) controlv ( 1 ) converter ( 1 ) copy ( 1 ) copy project ( 1 ) coupling ( 1 ) coverage ( 1 ) cp ( 1 ) css ( 1 ) cupertino ( 1 ) cursor ( 1 ) cv ( 1 ) data class ( 1 ) data structure ( 1 ) dataBinding ( 1 ) database ( 1 ) debounce ( 1 ) decompile ( 1 ) delegate ( 1 ) deno ( 1 ) design pattern ( 1 ) development ( 1 ) device ( 1 ) di ( 1 ) dialog ( 1 ) dio ( 1 ) drawable ( 1 ) drug ( 1 ) emmet ( 1 ) encoding ( 1 ) english ( 1 ) entries ( 1 ) environment ( 1 ) equality ( 1 ) equatable ( 1 ) euc-kr ( 1 ) euckr ( 1 ) exit ( 1 ) expand ( 1 ) expanded ( 1 ) export ( 1 ) extension method ( 1 ) facade ( 1 ) fake ( 1 ) field ( 1 ) figma ( 1 ) final ( 1 ) fixed ( 1 ) flutter pub ( 1 ) flutter web ( 1 ) flutter_inappwebview ( 1 ) flutter_test ( 1 ) flutterflow ( 1 ) fold ( 1 ) fonts ( 1 ) form ( 1 ) frame ( 1 ) future ( 1 ) gestureDetector ( 1 ) gestureRecognizer ( 1 ) gesturearena ( 1 ) get-command ( 1 ) get_cli ( 1 ) getbuilder ( 1 ) getx단점 ( 1 ) gitignore ( 1 ) glut ( 1 ) google fonts ( 1 ) gopath ( 1 ) goto ( 1 ) gradient ( 1 ) graphics ( 1 ) gvim ( 1 ) hackaton ( 1 ) hash ( 1 ) hashmap ( 1 ) hot reload ( 1 ) how to ( 1 ) html ( 1 ) i18n ( 1 ) icon ( 1 ) id ( 1 ) impeller ( 1 ) implementation ( 1 ) import ( 1 ) indicator ( 1 ) inkwell ( 1 ) interrupt ( 1 ) intl ( 1 ) introduction ( 1 ) io ( 1 ) isar ( 1 ) iterable ( 1 ) iteration ( 1 ) javascript ( 1 ) julia ( 1 ) juno ( 1 ) jupyter ( 1 ) kakaomap ( 1 ) keytool ( 1 ) korean ( 1 ) kotlin syntax ( 1 ) l10n ( 1 ) lambda ( 1 ) language ( 1 ) layer ( 1 ) layout ( 1 ) lineageOS ( 1 ) localkey ( 1 ) localtoglobal ( 1 ) long list ( 1 ) ls ( 1 ) mac osx ( 1 ) markdown ( 1 ) markup ( 1 ) material ( 1 ) method ( 1 ) microtask ( 1 ) migrate ( 1 ) mintlify ( 1 ) mock ( 1 ) module ( 1 ) monitor ( 1 ) moor ( 1 ) mouse ( 1 ) mouseregion ( 1 ) multiplatform ( 1 ) multiset ( 1 ) multithread ( 1 ) mutable ( 1 ) mvvm ( 1 ) new ( 1 ) node ( 1 ) nodejs ( 1 ) nosuchmethod ( 1 ) null-safety ( 1 ) numberformat ( 1 ) nvim ( 1 ) object ( 1 ) objectbox ( 1 ) objectkey ( 1 ) obx ( 1 ) online ide ( 1 ) operator ( 1 ) orientation ( 1 ) parabeac ( 1 ) parse ( 1 ) paste ( 1 ) path ( 1 ) pattern ( 1 ) pitfall ( 1 ) play store ( 1 ) pod ( 1 ) podfile ( 1 ) pointer ( 1 ) pointers ( 1 ) powershell ( 1 ) private ( 1 ) programming ( 1 ) pull to refresh ( 1 ) puzzle ( 1 ) pycharm ( 1 ) realitykit ( 1 ) recursion ( 1 ) reduce ( 1 ) reference ( 1 ) regex ( 1 ) regular expression ( 1 ) release note ( 1 ) renderbox ( 1 ) renderobject ( 1 ) repl ( 1 ) repository ( 1 ) response ( 1 ) rm ( 1 ) rotue ( 1 ) round ( 1 ) run ( 1 ) scope ( 1 ) scroll ( 1 ) search ( 1 ) server ( 1 ) serverless ( 1 ) service ( 1 ) sharp ( 1 ) singlerepo ( 1 ) singleton ( 1 ) sketch ( 1 ) sliver ( 1 ) sliverlist ( 1 ) snippets ( 1 ) sogae ( 1 ) sorting ( 1 ) source ( 1 ) sparse ( 1 ) sparse array ( 1 ) spec ( 1 ) split ( 1 ) sqflite ( 1 ) sqlite ( 1 ) sqrt decomposition ( 1 ) stateful ( 1 ) statefulwidget ( 1 ) step ( 1 ) stepper ( 1 ) string ( 1 ) stringbuffer ( 1 ) stringbuilder ( 1 ) studio ( 1 ) study ( 1 ) sub-directory ( 1 ) svn ( 1 ) swiftui ( 1 ) swipe to refresh ( 1 ) system_alert_window ( 1 ) system_cache ( 1 ) systemnavigator ( 1 ) tail recursion ( 1 ) tailrec ( 1 ) tap test ( 1 ) text ( 1 ) texteditingcontroller ( 1 ) textfield ( 1 ) texttheme ( 1 ) themedata ( 1 ) then ( 1 ) thread ( 1 ) throttle ( 1 ) time ( 1 ) tool ( 1 ) tools ( 1 ) tooltip ( 1 ) ts ( 1 ) tutorial ( 1 ) typescript ( 1 ) ui ( 1 ) unittest ( 1 ) update ( 1 ) usb ( 1 ) utf8 ( 1 ) ux ( 1 ) valuekey ( 1 ) variable ( 1 ) vector ( 1 ) versioncode ( 1 ) very_good ( 1 ) view ( 1 ) vim plugin ( 1 ) vimrc ( 1 ) virtualenv ( 1 ) wasm ( 1 ) web app ( 1 ) webview_flutter ( 1 ) while ( 1 ) widget tree ( 1 ) window ( 1 ) wsl ( 1 ) yield ( 1 ) 강의 ( 1 ) 개발 ( 1 ) 개발 공부 ( 1 ) 공부법 ( 1 ) 그래픽스 ( 1 ) 꼬리재귀 ( 1 ) 꿀팁 ( 1 ) 데노 ( 1 ) 두줄 ( 1 ) 디노 ( 1 ) 번역 ( 1 ) 블록 ( 1 ) 상태관리 ( 1 ) 실험 ( 1 ) 안드로이드 ( 1 ) 안드로이드프로젝트 ( 1 ) 안드로이드프로젝트복사 ( 1 ) 어이없는 ( 1 ) 조건부 임포트 ( 1 ) 주절주절분노조절실패의식으흐름 ( 1 ) 패키지 ( 1 ) 프로젝트복사 ( 1 ) 플러그인 ( 1 )