2012/03/26

Android:CursorAdapterコンストラクタの一部非推奨化

Android3.0以降、CursorAdapterコンストラクタの引数"flag"に制約が追加されました。
この変更はサブクラスであるResourceCursorAdapterやSimpleCursorAdapterにも影響します。

Android2.3.x以前は、コンストラクタの引数"flag"に設定可能な値としてFLAG_AUTO_REQUERY
が存在していましたが、Android3.0以降これは非推奨となりました。
http://developer.android.com/reference/android/widget/CursorAdapter.html#FLAG_AUTO_REQUERY

●非推奨となるAPI
注意すべきポイントは、flag指定を省略したコンストラクタである下記は、デフォルトで
flagにFLAG_AUTO_REQUERYを設定します。
CursorAdapter(Context context, Cursor c)

また、ResourceCursorAdapterやSimpleCursorAdapterが持つ下記コンストラクタも、
内部でCursorAdapter(Context context, Cursor c)を呼んでいるため非推奨となりました。
  • ResourceCursorAdapter(Context context, int layout, Cursor c)
  • SimpleCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to)

また、下記コンストラクタのautoRequeryにtureを設定するのもNGです。
CursorAdapter(Context context, Cursor c, boolean autoRequery)


●非推奨となった経緯
FLAG_AUTO_REQUERYは監視コンテンツの変更を検知した際に自動でrequeryさせるための
フラグです。
しかし、requeryによるクエリ実行処理はUIスレッド上で行われるため、パフォーマンス
上の観点から非推奨となりました。
# Android3.0でLoaderが追加されたように、UIスレッドでのクエリ実行は基本NGです。


●代替案
flagにはFLAG_REGISTER_CONTENT_OBSERVERをセットするか0を設定することです。
これらの値で初期化されたCursorAdapterはrequeryが実行されません。
また、autoRequeryは必ずfalseを設定するようにします。

クエリの再発行が必要である場合はCursorLoaderの使用を考えることができます。
Loaderによるクエリ実行はUIスレッドでは行われません。
下記のようにすれば、LoaderによるCursorの取得を契機にAdapterのCursorを更新するこ
とが可能です。

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

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor result) {
    mAdapter.swapCursor(result);
}
※LoaderManagerコールバック内で、結果セットを破棄(cursor.close)してはいけません。
CursorAdapter.changeCursor(Cursor)はcursorをcloseするため、ここではswapCursor(Cursor)
を使用する必要があります。

以上です。