à l'aide de ContentProviderClient vs ContentResolver pour accéder à un 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 de getContentResolver().acquireContentProviderClient(authority)
. Il semble plus ou moins les mêmes méthodes disponibles dans la ContentResolver
pour accéder au contenu à partir du fournisseur.
Quand dois-je utiliser un ContentProviderClient
au lieu de simplement en utilisant le ContentResolver
directement? Quels sont les avantages?
Vous devez vous connecter pour publier un commentaire.
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 deString contentAuthority
àContentProvider
. Lorsque vous appelezContentResolver.query()
ouupdate()
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 ainsi. 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é unContentProviderClient
qui est essentiellement un lien direct vers leContentProvider
. (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 utilisezContentProviderClient
, 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 permettra au système pour libérer le fournisseur, il détermine qu'il n'y a pas d'autre raison pour le garder actif". 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: Utilisation
ContentResolver
.Des appels répétés à la même Autorité: Obtenir et d'utiliser
ContentProviderClient
. N'oubliez pas de release() lorsque vous avez terminé.ContentProviderClient
autour. J'ai une application qui navigue sur le contenu à partir d'un fournisseur en particulier, il comprend un certain nombre d'activités. J'ai pu acquérir et de le libérer dans chaque activité, soit àonCreate
/onDestroy
ou àonStart
/onStop
; ou je pourrais mettre en cache une copie àApplication
niveau qui est sorti seulement lorsque toutes les activités (ou de la racine de l'activité) ont été détruits. Toutes les pensées?Ok, mais sachez qu'il ne fonctionne que lorsque ContentProvider s'exécutant dans le même processus que d'Activité.
Note de la documentation pour la méthode
getLocalContentProvider()
:Je pense que l'autre à l'importation différence est ContentProviderClient peut être jeté dans votre personnalisé objet fournisseur d'accès à d'autres méthode en plus de CRUD.
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é).
L'un des usages de ContentProviderClient est utile pour accéder à certaines méthodes de ContentProvider dans les tests. Pour exemple, j'utilise le shutdown() méthode dans les tests unitaires pour éviter de multiples tests d'instanciation de plusieurs fournisseurs de contenu.
Mettre en œuvre
ContentProvider#shutdown()
comme ceci:Et à la fin de la méthode d'essai, appelez
shutdown()
à l'aide de laContentProviderClient
pour nettoyer le test, alors que d'autres tests peuvent utiliser le fournisseur de contenu: