ContentProvider is an Android class for data exchange between applications It is exactly like this is written in javadocs : A content provider is only required if you need to share data between multiple applications But who reads the documentation while everything works? Obviously, only someone who’s had enough of stepping on all sorts of rakes.
So, in this post I would like to share my negative experience with using ContentProviders as a data source within an application. So why is it unreasonable to use them to access data inside an application?
The biggest problem, in my opinion, is that getContentResolver().query(…) returns either a cursor with data or null. If an exception appears inside the ContentProvider, the calling code has no way of knowing about it. The most you can find out by checking for null is the very fact that something went wrong.
For working within a single application, this approach is decidedly unsuitable, as sometimes the exception rises from the lowest data layer all the way down to the user interface. For example, a message about inaccessibility of a web service or an authorization error.
Of course, there is workaround. You can write error information to the cursor and process it in the calling code. But this is too artificial a solution.
Complex data structures
Cursor is only good as long as the returned data is representable as a table. But what if you need a more complex structure?
For example, a web service can return data page by page, with some meta-information on the first page, at least the number of pages. You could combine several cursors into one and parse them back in the calling code. But that would greatly complicate the logic at both the model and presenter levels.
Progress of execution
It is often necessary to track the progress of an operation. For example, to read a large amount of data from a file. ContentProviders do not provide this capability.
You can create private field, write current progress into it and return it by separate request. But here we have some problems with multithreading and parallel execution of several same requests from different clients by provider.
Code executed in ContentProvider, most likely won’t be able to stop. If we don’t use AsyncQueryHandler, we won’t have any control over the operation at all.
The workaround is about the same as in the previous problem – we start a private flag field, and switch it when the query needs to stop. In the query we constantly check flag state. This solution doesn’t work for all the same reasons.
The conclusion I can draw from the above is this. ContentProviders only make sense if they will be used to perform atomic operations, which do not take much time and return strictly homogeneous data that can be used by other applications. In all other cases, the use of ContetProviders seems unreasonable to me.