Does Android Content Provider authority definition break the DRY rule? -
android's content provider
must have:
at least 1 authority must specified.
so example in google's samples android-basicsyncadapter androidmanifest.xml there is
<provider android:name=".provider.feedprovider" android:authorities="com.example.android.basicsyncadapter" android:exported="false" />
then implement cp 1 need define same string inside cp in android-basicsyncadapter feedprovider.java content_authority
public static final string content_authority = "com.example.android.basicsyncadapter";
as have define string twice, isn't breaking dry rule - if change in 1 place, have remember change somewhere else well.
actually don't have specify authority multiple times. in our opentasks provider load authority @ runtime manifest.
the basic idea this:
context context = getcontext(); packagemanager packagemanager = context.getpackagemanager(); providerinfo providerinfo = packagemanager.getproviderinfo( new componentname(context, this.getclass()), packagemanager.get_providers | packagemanager.get_meta_data); string authority = providerinfo.authority;
on android 2.2 have take efforts since method getproviderinfo
not present yet.
optionally specify authority in string resource , refer manifest so:
<provider android:name=".provider.feedprovider" android:authorities="@string/authority" android:exported="false" />
in content provider load authority usual:
string authority = getcontext().getstring(r.string.authority);
it's bit more difficult if content provider serves multiple authorities, that's not idea anyway.
update follow comment:
i don't see problem providing context
contract.
instead of writing like
cursor c = contentprovider.query(mycontract.items.content_uri, null, null, null, null);
you write
cursor c = contentprovider.query(mycontract.items.itemsuri(getcontext()), null, null, null, null);
with
public final interface mycontract { // ... lots of other tables ... public final static class items { public final static string content_path = "items"; // contract definitions public final static uri itemsuri(context context) { return new uri.builder() .scheme("content") .authority(context.getstring(r.string.authority)). .path(content_path) .build(); } }
there not of difference, except can more convenient when need add id:
cursor c = contentprovider.query(mycontract.items.itemuri(getcontext(), myitemid), null, null, null, null);
passing context
these static methods not problem since need context anyway contentresolver
.
an advantage of technique code independent of actual authority , can import contentprovider
library different project different authority , don't need change single line of code.
btw prefer first version (loading authority manifest) since don't need string resource in case. can inject ${applicationid}
, never touch again.
the following manifest snippet guarantees authority unique each app import in:
<provider android:name=".provider.feedprovider" android:authorities="${applicationid}.myauthority" android:exported="false" />
Comments
Post a Comment