63 votes

utiliser ContentProviderClient vs ContentResolver pour accéder au fournisseur de contenu

La documentation sur Android les fournisseurs de contenu décrit à l'aide d'un ContentResolver, obtenu à partir de getContentResolver(), pour accéder au contenu.

Cependant, il est également ContentProviderClient, qui peut être obtenu à partir d' getContentResolver().acquireContentProviderClient(authority). Il semble plus ou moins les mêmes méthodes disponibles dans l' ContentResolver pour accéder au contenu à partir du fournisseur.

Quand dois-je utiliser un ContentProviderClient au lieu de simplement en utilisant l' ContentResolver directement? Quels sont les avantages?

92voto

jcwenger Points 6988

Votre appareil android dispose de nombreuses bases de données, dont chacun est identifié par un Contenu unique Autorité. C'est le "nom de domaine" partie équivalente dans le contenu:// uri-tout avant de la première barre oblique.

ContentResolver stocke les données et de fournir une cartographie de l' String contentAuthority de ContentProvider. Lorsque vous appelez ContentResolver.query() ou update() ou qu'avez-vous, l'URI est analysée à l'écart, dans ses composantes, la contentAuthority chaîne est identifiée, et contentResolver a pour lancer une recherche cartographique pour une chaîne correspondante, et de diriger les requêtes vers le bon fournisseur. Ce cher recherche se produit lors de chaque appel, parce que l'URI peut être différent d'un appel à l', avec un autre contentAuthority. En outre, il peut y avoir certains coûts liés à la création et à la déchirure en bas d'une connexion au fournisseur -- Il ne peut pas être réutilisées dans d'appels. Je ne suis pas sûr de la surcharge impliqué là-bas, c'est une assez profonde au niveau de l'OS de code.

En revanche, lorsque vous appelez acquireContentProviderClient(authority), que "le prestataire de ai-je besoin?" recherche est effectuée une fois, et vous êtes donné un ContentProviderClient , ce qui est essentiellement un lien direct vers l' ContentProvider. (Il y a un peu de colle entre vous et le fournisseur qui implique de la croix-fil de la communication et de la simultanéité de verrouillage). Toutefois, lorsque vous utilisez ContentProviderClient, vous vous adressez directement au Fournisseur pour l'autorité que vous avez demandé. Cela supprime les déchets de constamment re-calcul "le fournisseur qui je veux?"

REMARQUE: Par acquireContentProviderClient() documentation: Si vous obtenez un ContentProviderClient, "L'appelant doit indiquer qu'ils sont fait avec le fournisseur en appelant ContentProviderClient.release() qui va permettre au système afin de libérer le fournisseur, il détermine qu'il n'y a pas d'autre raison pour la garder active." Donc, essentiellement, en laissant un rassis Client ouvert, il peut forcer le Fournisseur pour continuer à fonctionner comme un service en arrière-plan. Donc, n'oubliez pas de nettoyer!

Résumé:

De nombreux appels à divers contentAuthorities: Utiliser ContentResolver.

Des appels répétés à la même Autorité: Obtenir et utiliser ContentProviderClient. N'oubliez pas de release() lorsque vous avez terminé.

7voto

Jokii Points 94

Ok, mais sachez que cela ne fonctionne que lorsque ContentProvider s'exécute dans le même processus que Activity.

Note de la documentation pour la méthode getLocalContentProvider() :

Si ContentProvider est exécuté dans un processus différent, la valeur null sera renvoyée. Cela peut être utilisé si vous savez que vous exécutez le même processus qu'un fournisseur et souhaitez obtenir un accès direct à ses détails d'implémentation.

4voto

guangmao.yu Points 21

Je pense que l’autre différence d’importation est que ContentProviderClient peut être transtypé dans votre objet fournisseur personnalisé et accéder à une méthode autre que CRUD.

 ContentProvider cp = getContentResolver().acquireContentProviderClient(mCurUri).getLocalContentProvider();
yourProvider fld = (yourProvider)cp;
fld.query(...);           // you can query as ContentResolver
fld.addFolder(newFolder); // also can invoke the extend method of your custom ContentProvider
 

2voto

mradlmaier Points 531

J'ai trouvé la différence suivante: J'ai écrit mon propre contentprovider en application A. J'ai écrit un Widget à l'écran d'accueil de l'App B. Quand j'ai essayé d'accéder à la ContentProvider de l'application via un ContentResolver de mon widget, j'ai eu un "impossible de trouver le fournisseur de l'info" erreur. Quand j'ai plutôt l'acquisition d'un ContentProviderClient par le biais de la ContentResolver et de la requête par le biais de la ContentProviderClient, il pourrait fonctionner. J'ai dû changer de rien d'autre, utilisez uniquement le ContentProviderClient au lieu de la ContentResolver. Je n'ai pas de réelle explication à ce comportement et n'a trouvé aucune information sur internet, pourquoi il est comme ça. Je ne sais pas, si c'est un caprice de widgets, parce que je n'ai pas l'essayer à partir d'une activité dans l'application B (app B est un simple widget, sans aucune activité).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X