I'm developing restful android application, but I'm still newbie to android, and I would like to avoid beginners bed structural design that would cost me troubles latter.
I've read lots of discussions about android services and restful applications, many of them contrary to each other, so I would like to know have I choosen a good approach.
Inspired by this presentation http://www.youtube.com/watch?v=xHXn3Kg2IQE I put my http requests into IntentServices, instead of the Async Task.
I've choose Intent Service because of:
as a services they are not sensitive to foreground/background switching like Activities (won't get killed).
Intent service provides work in separate thread, so the user interface stays responsive.
Since Intent Service cannot run multiple request simultaneously, I've "split" my domain into few groups and for each group I have written my Intent Service. (ends up in: one CRUD set -> one intent service)
This way I got that inside of a group can be only one request running at a time (And this is good for me, since this way it could never be executed for example update and delete at same unit).
And, on the other side, I can run multiple requests at the same time if they are from the other groups, and don't affect each other.
So basically, I have this:
one generic HTTPRequest class that builds requests from name value pairs
UserIntentService - creates user related requests and executes it by using HTTPRequest cass, and proccess request using UserProcessor. Notifies caller by intent with data.
CallIntentService - creates call related requests and executes it by using HTTPRequest cass
and proccess request using CallProcessor. Notifies caller by intent with data.
UserProcessor - parsing response
CallProcessor - parsing response
ServiceHelper - finds and starts right intent service
When using from activity, I use something like this: SeviceHelper.StartService (action, data),
and I get response by local BroadcastReceiver inside of the activity. I register receiver on the OnStart(), and unregister it on the onStop() method of the activity.
Is that a good approach?
Should I have only one IntentService for all calls?
Is it better to have one Service that runs all the time in background, instead of using Intent Service that has to be started for each request?
Is there any other things that can get bad with this approach that I'm missing?
Related
My app has a UI and a connection is made to a bluetooth device which is periodically sending barcode scan data to my app. I then want to cache this data in a sqlite db and have another process push this data up to a web server.
I have managed to get the UI and bluetooth scan process separated by using an Intent Service for the scanner component... The thread in the intent service connects to the bluetooth device and loops endlessly pulling in new scan data as it comes... communicating with the UI via broadcast messages as it needs to.
So now I need to handle storing the data in a sqlite db and pushing it up to the Internet.
I'm thinking I can insert a db row directly in the intent service loop I already have working for the bluetooth data... would I do that by firing of an async task or something like that?
Then, would I have a completely different intent service running and looping endlessly checking for new records to be processed and pushed up to my web server via an http post?
I guess the main reason I'm thinking of using intent services is that they seem to keep running even if I lock my phone and put it in my pocket... has worked so far for the bluetooth barcode scanner... can scan away happily with my phone locked and in my pocket.
I also need to handle the reality that internet won't always be available... hence the sqlite db... kind of like a safe buffer to store data until it can eventually be pushed up to the Web server.
Am I going down the right path? I'm really new to Android development and even after much research I'm still unsure about my approach.
You can store data or communicate from IntentService onHandleIntent() directly. You don't need to run it in separate thread, unless you want reading bluetooth to continue ASAP.
Handling everything in an infinite loop smells. Also keeping service alive depends on few factors. If IntentService dies, it won't be restored because by default IntentService.onStartCommand implicitly returns START_NOT_STICKY, or START_REDELIVER_INTENT if you call setIntentRedelivery(true) on this service. Check Service javadoc for more info.
If you can scan bluetooth periodically then I would consider kind of scheduler. For that you would probably need to implement Service, not IntentService and handle background thread yourself. Alternatively, you could use a Timer. These are more hints, not ready solution. Since you asked about direction, I assume you will investigate solutions yourself.
Depending on handled data you could separate DB operations and network to separate services. Think about them as modules which are decoupled. You will benefit maintaing this code in the future and in case one service goes down due to any reason, the rest will keep working. It depends on data size because it's not a good practise to push heavy data between service/activities(data is serialised and deserialised every time it is sent).
If DB is just a buffer/queue then maybe use it directly after reading bluetooth data. In other words queue data for sending. Create second service for HTTP communications. Don't push entire data to second service, just inform it about(knock the door :)) and let HTTP service access DB by itself. I would wrap DB in ContentProvider and access it from services.
There are probably different techniques out there too, but that's what I thought about it in the first place.
I have a two part question. Both are somewhat general.
I'm creating an app that relies heavily on communication with a server. I plan to have different classes for each repository I'll need. Is an Android service the correct pattern to use here? There may be certain situations where I'll want to cache things between activities. Will a service allow me to do this?
Assuming a service is what I want to use for this, how can I load content once the service is bound. When the user opens the app, I want to start loading content. However, binding a service isn't blocking, so I can't write the code that makes requests with the service in my onStart() right? Is there some helper class that will wait for the service to load then execute a function? I know I could put some code in my onServiceConnected() method but I'd like to stay away from coupling like that.
Hopefully that wasn't too abstract. Thanks in advance.
Yes, Service is the way to go, but a started service, not a bound one.
You could make async request methods, and the Service can broadcast the result back to your Activity.
The async request in this case is a startService(intent) with an
Intent containing the request parameters. The service would start a background thread for the operation, optimally you can use a networking library for this (for example Volley).
And the reply is a broadcast by the Service with the relevant data.
This answers the problem of caching, because the Service can decide what to return. So in case the Service does not have the requested resource, it will download (and return) it. But if the Service has the resource, then it will just simply return the cached version.
To start, you should get yourself familiar with these topics:
Started Services (for the requests)
LocalBroadcastReceiver (for the reply)
Event Bus (alternative to LocalBroadcastReceiver, for example Otto)
I don't know much about your concrete needs, but it seems like you want to implement a REST client with cache. There is a really good Google IO presentation on that here. Definately worth to watch!
1)If you need code to run even when your Activity isn't, the correct answer is a Service. If you just need to cache data, then storing it in a global static variable somewhere may be ok.
2)Your service can start a Thread or AsyncTask. These execute in parallel. onStartCommand generally launches it in this case.
As with most things, the answer to these questions are subjective at best. I would need more information then I currently have, but I'll take a vague, general stab at this...
If you need something persistently hitting your server repeatedly I would say use a service.
Where you call it is not nearly as important as how many times it needs to be called. That being said the answer is yes. If you need this data as soon as the application or activity loads, then the onCreate method is where it needs to be loaded.
My reccomendation is either A) service or B)AsyncTask.
Go with A if you have to hit the server repeatedly for data and need it in regular intervals. Otherwise go with an AsyncTask and load all the data you need into an object for storage. Then you can use it as you need and it will essentially be "cached".
The difference between the two is simply "best tool for the job". I see you use some javascript. To give a proper analogy, using a service for a server call rather than an async task, is the equivalent of using a web socket (node js) when you could of just used an ajax call. Hope this helps. Oh and PS, please don't use static variables in Android =).
My android application needs to communicate with a couple of Rest Services. Now i am decided to avoid using AsyncTasks for this. My architecture will be based on one Service and a couple of Intent Services. Each of my activity will send an intent containing parameters to a single service. Based on these parameters, the Service will invoke various IntentServices. The intent service will then perform the network operations and broadcast the result back into the calling activity. Is this approach correct ? Might be an idea for the Activity to directly invoke the IntentService ? What are the cons of this approach ?
Kind Regards
Use robospice :)
Motivation :
http://thumbnails.visually.netdna-cdn.com/RoboSpice_508a372b320e5.png
the WebApp i.e. the REST service should answer with a response very quickly (so the client app doesn't lock). If your request takes some time to process, the response should be 202. So you may have to look up that resource again, and that is indeed a nice job for AsyncTasks.
You can use RESTDroid that implements the service pattern designed by Virgil Dobjanschi in the Google IO video
I know that an activity can communicate with a local service using the IBinder interface; I am trying to find a way for communication between two services.
Specifically, I have my main service starting an IntentService to handle file uploads. I want this IntentService to inform back to the main service once it is done uploading, and before it dies.
Any ideas about how this would happen?
You have to use BroadcastReceiver to receive intents, and when you want to communicate simply make an Intent with appropriate values.
This way you should be able to make a 2-way communication between any component.
In Android, there is a special way of completing tasks like yours. Look at AIDL (it's not well documented in official docs, but there are some extra sources on the web). This is a way of implementing two-way communication between any components placed in separate processes. In comparison to BroadcastReceivers, using this you'd get direct calls and callbacks, that will be less dirty than relying on something would come from somewhere in BroadcastReceiver.
To reach the needed effect, you'll have to define an interface for a callback and an interface for performing actions (with a callback supplied, or register/unregister methods). Than, after you received some command using the second interface, you should perform the job and post back the result through callback. To reach the asynchronous completion add a key work "oneway" before method signature (return type). To separate in and out params (if you need it), use "in", "out" and "inout" keywords near params.
As it comes to restrictions, only primitives, arrays and parcelables (and parcelable arrays) might be transferred between processes.
To control your callbacks lifecycle and operations atomicity, use RemoteCallbacksList for storing registered callbacks and notifying recipients using the duplicate of your list got from beginBroadcast.
If you have any troubles, you're free to ask here.
I have to develop an application where i have to continuously collect the GPS, accelerometer data [esp. when user is in motion i.e traveling, else it can be relaxed). Also I have to communicate with web server and handle the response from the sever. So for this(handling response ) part application should continuously poll.
Based on response from server I have show UI to the user.
I am not very clear about the design.
Do I have to create activity from where I start service. Should service be ran as a separate thread(this always runs in background).
I am planning to create two services. One service to continuously collect GPS data.
Other service for communicating with the web server[start timer/alarm manager] for polling.
ALso can these two services communicate with each other.
Also after processing the response frm server the service should be able to start user interface to show some form. I am not clear how to handle this.
Also is acquiring wakelock required if I have to collect GPS data continuously.
Please clarify.
Thanks
You can use an AlarmManager for polling. You just need to set the interval. You will notice that most components Application, Service, Activity all are Contexts. So they all can get Application Context. The way to think about communication is that the android message/event is essentially the Intent. So you define your custom Intents. You just need to give them a custom name for the action. Then you use Intent filters. You can do point to point messaging by doing startService, startActivity or you can broadcast the intent. I would recommend that you communicate via broadcasted intents. Message routing is handled using Intent filters. Starting form etc would just be a startActivity(Intent) and the Intent itself could contain using intent.getExtras(). Just so long as you can put it in the Bundle you can pass it and display. So to answer your question, just use Intents for everything. Use broadcasting and filtering for communication and Intents again to start your activity for display.
The May 10th Google I/O had an afternoon session called Android Pro Tips. The first section covered several different approaches to making your app more continuously location aware.