AsyncTaskLoader の使い方 (7/8) 〜 データベースと CursorLoader

AsyncTaskLoader___Android_Developers

AsyncTaskLoader | Android Developers


目次

1. Thread と AsyncTask
2. AsyncTaskLoader の利点
3. LoaderManager の利用
4. よくある間違いと回避法
5. 基本的な Loader の実装
6. いろいろな Loader の使用例
7. データベースと CursorLoader
8. Loader の弱点を克服する


7. データベースと CursorLoader

CursorLoader は ContentProviders 照会専用のローダです

結果としてデータベースカーソルを返す。

AsyncTaskLoaderを継承したバックグランドスレッドでデータベースクエリーを実行します。

Acitivityのライフサイクルに応じて、Activity.startManagingCursor(Cursor c) やカーソルのライフサイクルの管理を置き換えます。
→ close() は呼ばない。

データベースを監視し、データが変更された新しいカーソルを返します。
→ requery() は呼ばない。

ListFragment内 CursorAdapterでの使い方

@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    return new BookmarksLoader(getActivity(), 
        args.getDouble("latitude"), args.getDouble("longitude")); 
}

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    adapter.swapCursor(data); 
    // The list should now be shown. 
    if (isResumed()) { 
        setListShown(true); 
    } else { 
        setListShownNoAnimation(true); 
    } 
}

@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
    adapter.swapCursor(null); 
}

続きを読む >>


AsyncTaskLoader の使い方 (6/8) 〜 いろいろな Loader の使用例

AsyncTaskLoader___Android_Developers

AsyncTaskLoader | Android Developers


目次

1. Thread と AsyncTask
2. AsyncTaskLoader の利点
3. LoaderManager の利用
4. よくある間違いと回避法
5. 基本的な Loader の実装
6. いろいろな Loader の使用例
7. データベースと CursorLoader
8. Loader の弱点を克服する


6. いろいろな Loader の使用例

代わりにグローバルなキャッシュ利用する

public abstract class GlobalCacheLoader<T> extends AsyncTaskLoader<T> { 
    ... 
    @Override 
    protected void onStartLoading() { 
        T cachedResult = getCachedResult(); 
        if (cachedResult != null) { 
            // 結果が利用可能であればすぐに配送
            deliverResult(cachedResult); 
        }
        if (takeContentChanged() || cachedResult == null) { 
            // 最終読み込み時のデータが変更されているか、
            // または、利用不可(null)の場合
            forceLoad(); 
        } 
    } 
    ... 
    protected abstract T getCachedResult(); 
}

データ監視部分

* onContentChanged() 
    Loader が開始されていたら forceLoad()、停止していたら フラグをセット。 
* takeContentChanged() 
    フラグの値を返して、クリアする。 
@Override 
protected void onStartLoading() { 
    if (mResult != null) { 
        deliverResult(mResult); 
    }
    if (takeContentChanged() || mResult == null) { 
        forceLoad(); 
    } 
}

続きを読む >>


AsyncTaskLoader の使い方 (5/8) 〜 基本的な Loader の実装

AsyncTaskLoader___Android_Developers

AsyncTaskLoader | Android Developers


目次

1. Thread と AsyncTask
2. AsyncTaskLoader の利点
3. LoaderManager の利用
4. よくある間違いと回避法
5. 基本的な Loader の実装
6. いろいろな Loader の使用例
7. データベースと CursorLoader
8. Loader の弱点を克服する


5. 基本的な Loader の実装

・ Loader 
    ベースとなる抽象化クラス。
・ AsyncTaskLoader 
    Loader の拡張。
・ CursorLoader 
    AsyncTaskLoader の拡張。 
    ContentsProvider 専用。

AsyncTaskLoader の制限事項

private static final int CORE_POOL_SIZE = 5; 
private static final int MAXIMUM_POOL_SIZE = 128; 
private static final int KEEP_ALIVE = 1; 
public static final Executor THREAD_POOL_EXECUTOR 
    = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, 
                                KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); 
private static volatile Executor sDefaultExecutor = THREAD_POOL_EXECUTOR;

内部的に ModernAsyncTask を使用している。

重要: ローダーにアプリケーションのコンテキストの参照のみを保持させることでリークを避ける。

/** 
 * コンテキストに関連付けられているアプリケーション·コンテキストを格納する。
 * ローダーは複数のアクティビティで使用できるので、直接コンテキストを保存することは危険。
 * 
 * @param context アプリケーション・コンテキストを取得するために使用
 */ 
public Loader(Context context) { 
    mContext = context.getApplicationContext(); 
}

Loader 内部クラスの各々は、staticとして宣言されなければならない、さもなければ親への暗黙の参照を維持してしまう。

続きを読む >>