Presentation
DataDroid is an Android Library which will ease the developement of Android applications when you have to manage local data or to call REST webservices for remote data. It is compatible with 2.2+ applications.
During the Google I/O 2010, a session was aired about how to handle REST webservices in an Android application. For those who didn’t see it yet, here is the video of the presentation :
This presentation was really interesting but unforTunately it was only theorical and didn’t include any code to help the developers to implement the solutions proposed. DataDroid allows you to easily implement the first solution shown in the session.
Features
Before showing how to add DataDroid to your project, let’s see what you will be able to do with it :
- Local data management in a SQLite database
- Local data management in memory
- REST Webservices calls with management of configuration changes (orientation for example) and Activities hiding for a phone call for example
The project contains :
- The Android Library containing all the classes needed
- A proof-of-concept project containing samples of code using the Android Library for the different use cases explained here
Architecture
Here is what’s happening when you makes a webservice call using DataDroid :
(click the image to see it in full size)
- The
Activity
create aRequest
(in this example using aRequestFactory
).
TheRequest
object contains the following data :- A request type (integer) allowing you to distinguish the different type of
Request
s you have. - A boolean to know whether to save the data received from the
Operation
in the memory cache or not - Parameters for the request (key => value pattern)
- A request type (integer) allowing you to distinguish the different type of
- The
Activity
calls theexecute()
method ofRequestManager
.
In the method, a check is automatically made to see if the same request call is already in progress.- If it’s the case, the given RequestListener is added to the current request call.
- Otherwise a new request call is also created.
- The
RequestManager
forwards theRequest
to theRequestService
if it's not already in progress. - The
RequestService
creates theOperation
corresponding to the received request type and gives it the Request. - The
Operation
uses the providedNetworkConnection
class to make the webservice request and parse the result.- If a connection error occurs during the webservice call, it is sent back to the
RequestManager
. And it will be transmitted to theRequestListener
(more information about that below). - Same thing for a data error while parsing the data or saving the data in the database
- You can also if needed throw a
CustomRequestException
. In this case, you are getting called back in theRequestService
if you have overridden the methodonCustomRequestException()
.
This allows you to provide additional information based on the exception you threw. As for the connection error, it is sent back theRequestManager
and then to theRequestListener
.
- If a connection error occurs during the webservice call, it is sent back to the
- Depending on your case, you can then either save your data in a
ContentProvider
or send it back to the callingActivity
usingParcelable
objects.- If you save your data in a
ContentProvider
, you can use aCursorLoader
in your Activity to retrieve your data. - If you use
Parcelable
objects, you just have to add them to the returnedBundle
.
You should also set the flag in yourRequest to cache your data in memory.
- If you save your data in a
- Finally a
RequestListener
callback is called from theRequestManager
:-
onRequestFinished(request, resultData)
if the request was executed without problems. -
onRequestConnectionError(request, statusCode)
if a connection error occurred while executing the request. -
onRequestDataError(request)
if a data error occurred while executing the request. -
onRequestCustomError(request, resultData)
if aCustomRequestException
was thrown during the execution of the request.
in this case,resultData
contains the additional information provided if you have overridden the methodonCustomRequestException()
.
-
If your Activity
was not listening anymore when the request finished its execution (for example a phone call is currently occurring), you will not be called back as you have unregistered your listener in the onPause()
method.
On your next onResume()
when you want to register again your listener, you can check if your request is still in progress using the isRequestInProgress(request)
method of RequestManager
.
- If that's the case, just register again your listener.
- Otherwise, if you have enabled the memory cache for your request (ie you are using
Parcelable
objects), you can use thecallListenerWithCachedData(requestListener, request)
method.- If there is some cached data available, the method
onRequestFinished(request, resultData)
of the listener will be called with the cached data. - Otherwise the method
onRequestConnectionError(request, statusCode)
will be called.
- If there is some cached data available, the method
Share this:
Place your comment
Latest posts
Archives
- April 2013 (1)
- February 2013 (1)
- January 2013 (3)
- December 2012 (1)
- November 2012 (1)
- September 2012 (1)
- June 2012 (1)
- April 2012 (1)
- August 2011 (1)
Blogroll
[...] en cours d’envoi. Une description complète est disponible sur le site de la librairie : http://datadroid.foxykeep.com/presentation. A noter que plusieurs exemples sont disponibles via l’application DataDroid PoC que vous pouvez [...]
[...] en cours d’envoi.Pour consulter une description complète de DataDroid voici le lien : (link)Pour l’installation voici le lien : (link) Share and Enjoy: TweetRelated [...]
[...] http://www.datadroidlib.com/presentation [...]
Bravo pour cette nouvelle release. On dirait bien que RoboSpice a un concurrent sérieux
Félicitations !
Stéphane
Merci !
Hi foxykeep, first of all thank you for the library, I’ve been reading a lot these days and I find your architecture & implementation the most robust. Cyril Mottier forking it definetely convinced me!
On the DB persistence topic, from what I understand it should be done inside the Operation’s execute(), right? I’d get access to the content provider through the context and insert/delete/update
I’m asking because I couldn’t find an Operation that does this in the example project.
Thanks again!
btw: this comment box looks horrible on Chrome@Mac. Overlaps everywhere.
Also, I’m considering getting rid of the ContentProvider as I don’t intend to share any content from my app. I’d access the DB directly in the Operation and use a custom CursorLoader that doesn’t need a ContentProvider.
Any advice against this path?
Thanks again!
Ok, I just noticed you already explain it in this post. Sorry for not reading before.
Anyway, the question about not using a contentprovider is still there.
Thanks and sorry for the spam.
About an example Operation using a ContentProvider, you can check PersonListOperation in the sample project.
About using direct DB access instead of a ContentProvider, I have nothing against it. I just found using a ContentProvider cleaner and simpler (especially if you use my ContentProviderCodeGenerator to write all the code for you ^^)
Hi foxykeep,
I have been looking at your datadroid library and I have been playing with the datadroidpoc application, in particular the Person List (DB).
I have a question which I’m unable to figure out how to answer…
Say for example that a Person has name, address, AND a list of rental properties.
The list of rental properties could potentially be from 1 to thousands.
Let’s assume that rental properties can not be shared among different people.
Here are my questions:
1. in the database, should the rental property data be in a separate table RENTALPROPERTY and somehow there should be an association between the PERSON table and the RENTALPROPERTY table. Correct?
2. I’m not sure how I would implement that in the Person List example. Could you please give me ideas?
3. If I wanted to display the Person list in an expandable list with name and address first and then when a specific person is clicked, I would display the list of rental properties. In that case, when displaying the person list, would the list of rental properties for each person fetched from the database be also fetched (even if I’m not displaying until a specific person is clicked)?
4. Is there a way to only load and query the list of property rentals only when a person is selected?
Any ideas would be greatly appreciated.
I replied to your questions in your email
Hello foxykeep,
I’m writing an app using DataDroid and can’t seem to find how to edit Body of request (method: PUT). Need to execute smth like this:
PUT …/vmrest/messages/
false
Does it support request body editing at all?
thanks
in prev. post after “smth like this:” should be
PUT /vmrest/messages/messageid
-Message-
-Subject-New subject-/Subject-
-/Message-
Update your datadroid version to the latest one on GitHub. I’ve just uploaded this morning a fix for this use case. There is now a setPostText(String text, Method method) method in NetworkConnection which allows you to use PUT method with post data.
thanks
worked like a charm