• No results found

While content providers have their weaknesses, they also have their strengths and can, at times, make things easier. The following sections detail why the use of content providers can be advantageous.

Abstraction Layer for Structured Data

Content providers are good at hiding the details of data storage and retrieval from apps. Because a content provider is actually an interface to structured data, the actual mechanism of data storage is irrelevant to other app components. For example, a content provider can expose data that is stored in a database, stored as files on disk, or even stored on a remote system and accessed via a Web service. Because those other components never know the details of how the data is stored, the storage mechanism can change without affecting any of a content provider’s clients (assuming the contract classes don’t change).

The content provider also allows all data store information to be accessed the same way whether the client accessing the data is the local component or an external app. Pro-viding a single interface for all data access, whether local or remote, limits the complexity around data access.

Most apps that need to persist data to a database need a layer that handles interfacing between the database and the rest of the business logic. In Android, the content provider is a natural option for that layer that offers many benefits over other architectures.

Well Supported by Other Android Components

Content providers are well supported across the Android SDK (with the exception of the data binding API as discussed previously) when using other Android components. One of the most convenient uses of a content provider is with a cursor loader. The Android docs make a strong claim that a content provider should be used when using a cursor loader.

While it is possible to use a cursor loader without a content provider, it can make the cursor loader implementation more complex.

Cursor loaders can be a great way for apps to eliminate the complexity of manually supporting configuration changes in activities and fragments. In addition, loaders handle the asynchronous nature of loading data from a database off the UI thread while providing the results of a database operation (usually a query) on the main thread allowing UI updates. Recall from the discussion of cursor loaders in Chapter 5 that neither the cursor loader nor the activity needs to explicitly make calls to a content resolver or content provider when using a cursor loader. This is because the cursor loader handles these tasks on its own.

Once a content provider is implemented, making use of a cursor loader to load data to the UI is pretty straightforward and does not require much code. Additionally, activity lifecycle events, as they relate to cursor objects, are handled by the Android system, freeing the developer from worrying about memory leaks from a cursor that was not closed.

ptg18221911

Summary 135

In addition to cursor loaders, the sync adapter and the search API make use of content providers. In some cases, certain APIs mandate the use of a content provider.

Handles Interprocess Communication

One of the major strengths of content providers is that they allow apps to easily send data across process boundaries. This can foster communication between two different apps, or even within a single app that needs to run across two different processes. As discussed earlier in the chapter, the interaction between the content resolver and a content provider allows this interprocess communication to happen transparently in apps.

Android does provide other mechanisms to send data between components that are running in two different processes. One alternative approach is to use a bound service and define an Android Interface Definition Language (AIDL) interface for interprocess communication. While this allows communication to take place, it does not always fit the needs of an app.

Services are good at supporting long-running tasks that need to happen in the

background with no UI. While they can be used to transfer data across a process boundary, services do not seem like a good fit if that long-running use case is not needed. In addition, a service still needs to make calls to the database to retrieve the data, then manually manipulate it so it can be sent to another process.

Summary

Content providers can be a convenient way to both expose internal data to external apps and provide an abstraction layer between an app’s database and UI logic. When used with a content resolver, a developer does not need to worry about the details of getting data from one process to another.

By setting permissions, apps can also control the level of access an external app will have to the data they provide. This provides flexibility when deciding to allow external apps to have access to an internal database.

When coupled with the use of a cursor loader, a content provider can be a useful Android component for handling chores normally associated with data access in Android.

The next chapter dives deeper into the details of using cursor loaders to load data into views that are displayed to a user.

ptg18221911

ptg18221911