ContentProvidersのダークサイド

ContentProviderは、 アプリケーション間でデータを交換するためのAndroidクラスです 。 これはまさにjavadocsで書かれたものです 。コンテンツプロバイダーは、複数のアプリケーション間でデータを共有する必要がある場合にのみ必要です 。 しかし、すべてが機能している間にドキュメントを読むのは誰ですか? 明らかに、すべての種類の熊手を踏んで十分な円錐を満たした人だけ。



そのため、この記事では、アプリケーション内のデータソースとしてContentProvidersを使用することについての否定的な経験を共有したいと思います。 プログラム内のデータにアクセスするための使用が正当化されないのはなぜですか?





例外処理


私の意見では、最も重要な問題はgetContentResolver()。Query(..)がデータカーソルまたはnullを返すことです。 ContentProvider内に例外が表示された場合、呼び出し元のコードはそれを認識しません。 nullをチェックすることでわかる最大値は、何かがうまくいかなかったという事実です。



1つのアプリケーション内で作業する場合、このアプローチは間違いなく適切ではありません。例外は、最低のデータレベルからユーザーインターフェイスまで上昇することがあるためです。 たとえば、Webサービスが利用できない、または認証エラーに関するメッセージ。



もちろん、回避策があります。 エラー情報をカーソルに書き込み、呼び出しコードで処理できます。 しかし、これは人工的な解決策です。



複雑なデータ構造


カーソルは、返されたデータがテーブル化可能である限り正確です。 しかし、より複雑な構造が必要な場合はどうでしょうか?



たとえば、Webサービスはページごとにデータを返すことができますが、最初のページには少なくともページ数のメタ情報があります。 複数のカーソルを1つに結合し、呼び出し元のコードで逆アセンブルできます。 ただし、これにより、モデルレベルとプレゼンターレベルの両方でロジックが大幅に複雑になります。



進捗状況


多くの場合、操作の進行状況を追跡する必要があります。 たとえば、ファイルから大量のデータを読み取ります。 ContentProvidersはこの機能を提供しません。



プライベートフィールドを作成し、現在の進行状況を書き込み、別のリクエストで返すことができます。 しかし、ここではすぐに、異なるクライアントからのいくつかの同一のリクエストのプロバイダーによるマルチスレッドと並列実行に問題が生じます。



実行を停止


ContentProviderで実行されるコードは、 ほとんどの場合停止できません。 AsyncQueryHandlerを使用しない場合、通常、操作を制御できません。



回避策は、前の問題とほぼ同じです。プライベートフラグフィールドを設定し、リクエストを停止する必要があるときに切り替えます。 リクエストでは、フラグの状態を常にチェックしています。 このソリューションは同じ理由で適合しません。



おわりに





上記からの結論、私はこれを行うことができます。 ContentProviderを使用するのは理にかなっています。Atomic操作は、その中で原子操作が実行される場合にのみ有効です。 ここでは、ContetProviders'ovの他のすべての使用は不当に思えます。



All Articles