티스토리 뷰
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
CursorLoader usage without ContentProvider
ContentProvider 없이 CursorLoader 사용 방법
문제 내용
Android SDK documentation says that startManagingCursor()
method is depracated:
안드로이드 SDK 문서에 따르면 startManagingCursor() 메서드는 더 이상 사용되지 않는다고 나와 있습니다.
This method is deprecated. Use the new CursorLoader class with LoaderManager instead; this is also available on older platforms through the Android compatibility package. This method allows the activity to take care of managing the given Cursor's lifecycle for you based on the activity's lifecycle. That is, when the activity is stopped it will automatically call deactivate() on the given Cursor, and when it is later restarted it will call requery() for you. When the activity is destroyed, all managed Cursors will be closed automatically. If you are targeting HONEYCOMB or later, consider instead using LoaderManager instead, available via getLoaderManager()
이 메소드는 더 이상 권장되지 않으며 대신 LoaderManager와 함께 새로운 CursorLoader 클래스를 사용하십시오. 이는 Android 호환 패키지를 통해 이전 플랫폼에서도 사용할 수 있습니다. 이 방법은 활동의 수명 주기를 기반으로 주어진 Cursor의 수명 주기를 관리하도록 활동이 관리할 수 있게 해줍니다. 즉, 활동이 중지되면 주어진 Cursor에서 deactivate()가 자동으로 호출되고, 나중에 다시 시작되면 requery()가 자동으로 호출됩니다. 활동이 파괴될 때 모든 관리되는 Cursor가 자동으로 닫힙니다. HONEYCOMB 이상을 대상으로 하는 경우 getLoaderManager()를 통해 대신 LoaderManager를 사용하는 것이 좋습니다.
So I would like to use CursorLoader
. But how can I use it with custom CursorAdapter
and without ContentProvider
, when I needs URI in constructor of CursorLoader
?
그러므로 CursorLoader를 사용하고 싶습니다. 그러나 ContentProvider 없이 커스텀 CursorAdapter와 함께 사용하고 URI를 CursorLoader의 생성자에서 필요로 할 때는 어떻게 해야 할까요?
높은 점수를 받은 Solution
I wrote a simple CursorLoader that does not need a content provider:
제가 간단한 커서 로더를 작성했는데, 이것은 콘텐트 프로바이더가 필요하지 않습니다.
import android.content.Context;
import android.database.Cursor;
import android.support.v4.content.AsyncTaskLoader;
/**
* Used to write apps that run on platforms prior to Android 3.0. When running
* on Android 3.0 or above, this implementation is still used; it does not try
* to switch to the framework's implementation. See the framework SDK
* documentation for a class overview.
*
* This was based on the CursorLoader class
*/
public abstract class SimpleCursorLoader extends AsyncTaskLoader<Cursor> {
private Cursor mCursor;
public SimpleCursorLoader(Context context) {
super(context);
}
/* Runs on a worker thread */
@Override
public abstract Cursor loadInBackground();
/* Runs on the UI thread */
@Override
public void deliverResult(Cursor cursor) {
if (isReset()) {
// An async query came in while the loader is stopped
if (cursor != null) {
cursor.close();
}
return;
}
Cursor oldCursor = mCursor;
mCursor = cursor;
if (isStarted()) {
super.deliverResult(cursor);
}
if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
oldCursor.close();
}
}
/**
* Starts an asynchronous load of the contacts list data. When the result is ready the callbacks
* will be called on the UI thread. If a previous load has been completed and is still valid
* the result may be passed to the callbacks immediately.
* <p/>
* Must be called from the UI thread
*/
@Override
protected void onStartLoading() {
if (mCursor != null) {
deliverResult(mCursor);
}
if (takeContentChanged() || mCursor == null) {
forceLoad();
}
}
/**
* Must be called from the UI thread
*/
@Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
@Override
public void onCanceled(Cursor cursor) {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
if (mCursor != null && !mCursor.isClosed()) {
mCursor.close();
}
mCursor = null;
}
}
It only needs the AsyncTaskLoader
class. Either the one in Android 3.0 or higher, or the one that comes with the compatibility package.
이것은 AsyncTaskLoader 클래스만 필요로 합니다. 안드로이드 3.0 이상 버전의 것이나 호환성 패키지에 포함된 것 중 하나를 사용할 수 있습니다.
I also wrote a ListLoader
which is compatible with the LoadManager
and is used to retrieve a generic java.util.List
collection.
또한, 저는 LoadManager와 호환되며 일반적인 java.util.List 컬렉션을 검색하는 데 사용되는 ListLoader도 작성했습니다.
가장 최근 달린 Solution
A third option would be to simply override loadInBackground
:
세 번째 옵션은 loadInBackground를 단순히 오버라이드하는 것입니다.
public class CustomCursorLoader extends CursorLoader {
private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver();
@Override
public Cursor loadInBackground() {
Cursor cursor = ... // get your cursor from wherever you like
if (cursor != null) {
// Ensure the cursor window is filled
cursor.getCount();
cursor.registerContentObserver(mObserver);
}
return cursor;
}
};
This will also take care of re-querying your cursor when the database changes.
이렇게 하면 데이터베이스가 변경될 때 커서를 다시 쿼리하는 것도 처리됩니다.
Only caveat: You'll have to define another observer, since Google in it's infinite wisdom decided to make theirs package private. If you put the class into the same package as the original one (or the compat one) you can actually use the original observer. The observer is a very lightweight object and isn't used anywhere else, so this doesn't make much of a difference.
유일한 주의점은 Google이 그들의 무한한 지혜로 패키지 프라이빗으로 만든 것 때문에 또 다른 observer를 정의해야 한다는 것입니다. (이미 original 또는 compat one과 같은 패키지에 클래스를 넣은 경우에는 원래의 observer를 사용할 수 있습니다.) observer는 매우 가볍고 다른 곳에서 사용되지 않으므로 큰 차이가 없습니다.
출처 : https://stackoverflow.com/questions/7182485/cursorloader-usage-without-contentprovider
'개발 > 안드로이드' 카테고리의 다른 글
현재 스레드가 메인 스레드(main thread)가 아닌지 확인하는 방법 (0) | 2023.03.08 |
---|---|
ScrollView의 끝 감지하기 (0) | 2023.03.08 |
안드로이드에서 딜레이 후 메소드 호출하기 (0) | 2023.03.07 |
Android를 사용하여 HTTP 요청 만들기 (0) | 2023.03.07 |
LocalBroadcastManager를 사용하는 방법 (0) | 2023.03.06 |