2012/08/06

Android:JellyBean以降のContentResolver.queryの挙動


事の発端は下記の投稿。
Issue 35610:  Why does getContentResover().query() acquire IContentProvider twice but leave the stable one only?  

JellyBeanで追加されたacquireUnstableProviderメソッド。
この変更がContentResolverやContentProviderClientにも波及している。

特にContentResolverのqueryやopenAssetFileDescriptorの変更は興味深い。
ContentResolver.java (r4.1.1)

まず、unstableなプロバイダを取得してクエリを発行。
qCursor = unstableProvider.query(uri, projection,
        selection, selectionArgs, sortOrder, remoteCancellationSignal);
取得したqCursorはCursorWrapperInnerでラップして、stableなプロバイダと紐付けさせている。
CursorWrapperInner wrapper = new CursorWrapperInner(qCursor,
        stableProvider != null ? stableProvider : acquireProvider(uri));
最後に、要らなくなったunstableなプロバイダをリリース。
} finally {
    if (unstableProvider != null) {
        releaseUnstableProvider(unstableProvider);
    }
なぜこんな処理をしているのか?
Issue 35610を投稿した方も色々疑問に思っているみたいですが、、、

プロバイダ側プロセスの死亡で道連れ死する期間を小さく抑えているのか?
はたまた、パフォーマンス的な問題なのか?

はっきりした答えがありませんが、
JellyBeanからContentResolver.queryの挙動が若干変わったことは覚えておいたほうが良さそうです。

以上です。