[Android] Using Projects to Separate Content Provider from Application Code

Content providers can be used to store and share data between two or more applications. The applications are usually independent of each other and they do not need to know the content provider stores and retrieves its data. Instead of lumping all of them together in one project, I generally find it easier to work with when they are separated out into their own individual projects. In this example (downloadable from here), this is separated in to four projects:

  1. CategoryEditor – Contains a ListActivity for editing the Categories.
  2. CategoryField – Contains another activity that displays the Categories in a combo box.
  3. CategoryProviderApi – Contains an API for other projects to make use of the content provider.
  4. CategoryProviderImpl – Contains the content provider implementation.

The reason for this separation is because the activities in CategoryEditor and CategoryField do not need to know the implementation details of the content provider – how it stores its data and how it retrieves it. All they require is the information contained in CategoryProviderApi. In fact, CategoryProviderApi contains only a single class that provides constants for the other applications to access the content provider.

To use this kind of structure, the CategoryProviderApi must first be marked as a library. This is done via the Android properties:

Next, the other projects are referencing this project (including CategoryProviderImpl). In the Android properties in each of the projects, they need to add CategoryProviderApi

We also have to declare the content provider in an AndroidManifest.xml file. With the projects separated like this, we could still place this information inside the manifest for CategoryProviderImpl. The manifest would look something like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      android:versionCode="1"
      android:versionName="1.0" package="org.kah.provider">
	<application>
		<provider android:authorities="org.kah.categories"
			android:name="TasksProvider">
		</provider>
	</application>
</manifest> 

However, this would make CategoryProviderImpl look like another application and you would have to install this into the emulator or phone separately from the other applications.

Alternatively, we could make CategoryProviderImpl another library and have one of the project’s manifest declare the provider. However, this would require the application declaring the content provider to be installed first. Furthermore, if the user chooses to uninstall the application declaring the content provider, than the other application will no longer have access to the same content provider. Unfortunately, I’m not aware of any other solutions that do not have this draw backs. Please, feel free to leave a comment if you do know of a better way or suggestions.

Advertisements

6 Responses to [Android] Using Projects to Separate Content Provider from Application Code

  1. Ron Albury says:

    I am a long time programmer who is *just now* looking at android. I believe your separation of application code and content provider is good style. I don’t think it is necessarily a bad thing that you install the content provider separately – this would allow you to update your applications data without having to update the application. Maybe that’s not an issue for you, but it seems sound to me.

    If I am isolating the content provider, would I want to install it as an application or a service?

    • Ron Albury says:

      Sorry – what I meant to say is would it be better to install it as a provider or a service? I am from the J2EE world, and the analogy I have is that a provider is like my database and a service is like a bean. I don’t particularly care for RESTful services and tend to always access the database thru session beans.

      I am also unclear on local vs remote services. I realize a remote service allows multiple applications to access the service … but what if my application wants to access multiple separately installed services? Do I need to go the remote route?

      • kahgoh says:

        Hi,

        I think it would be better to do it as a service. There should be something that is uses your provider. I’d imagine that it would be your service that accesses your provider (directly, anyway). Content providers aren’t particularly useful on their own either. From the user’s point of view, I think it is better if they could just install all of your applications activities, services, content providers and broadcast receivers in one go. In most of cases, I think you should be able to do this.

        I would probably only give preference to installing a provider on its own if there were multiple independent applications accessing the same provider and that the provider should still be around for the other applications when one of them is uninstalled. I think this would be rare though.

  2. Hi, Can you explain briefly about this.

    Actually ,After adding the library what happen to the other application? Is necessary to do this?

    • kahgoh says:

      Not sure if I understood you correctly. It isn’t necessary develop your app into separate projects though. Some people may prefer to divide into project and others might not – its really each project, team or person to decide how to they want to organise their project.

  3. Steve Webb says:

    I’ve commented on issues with using ContentProviders elsewhere. I started looking into using one for a series of apps I was looking at writing, however I had a similar issue. You need to provide the provider with one of the apps but which one, you don’t know which one a customer would download first. Also if you provided it with all apps that wouldn’t work because Android provides no configuration setting for defining if a provider should be upgraded from another app, not downgraded …….

    With these things in mind, the lack of installation configuration and the inability to use them for several of your own apps they strike me as a total waste of time. They are heavy weight to code, they add extra logic that slows down processing and uses battery power and offer nothing extra in MVC terms.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: