Android application design: Right split between activities, services and threads? - android

I'm currently trying to finish the design of a larger app which is used for remote controlling wireless devices via a proprietary wireless bridge, a USB host device using CDC.
But right now I'm stuck in how to make the correct split between Activities, Services / IntentServices and worker threads.....
The application will be made of these fundamentals:
- Various GUI screens which offcourse will all be Activities. I intend to have some threads for receiving a few messages and updating the GUI accordingly via handlers upon these message receptions. - any comments on that approach?
A module handling all low level USB/CDC communiation, message serialization/deserialization and message dispathing to the application via queues. This calls for a seperate thread. I don't want this thread to be destroyed just because the activity that spawned it goes away - which in my book calls for an IntentService - right?
Some sequence players which will control the wireless devices in a timed manner. These will be triggered from one my activities and MUST run to the end without stopping due to home button presses, launch of other activities etc. - Again this calls for a IntentService.....right?
A status module updating some "global" data structures (possibly a database) upon message reception from the low level module. Here I am puzzled...coulmd this just be a working thread in my main Activity - or am I looking at a third IntentService?
Would it be better to include all in one service and then just add threads where needed?
Sorry for my noobiness - Android is hard for C++ programmers who have been programming non GUI backgroud tasks for the last century.
Thanks in advance!!!

For bullets one and two you are right that a service is the best approach. An IntentService in particular is good to handle jobs one by one that were sent from somewhere else.
If your service should only keep a particular thread alive which does the message/queue handling on its own (as I understand bullet one), a normal service may be enough.
For bullet three it depends if those updates must be done while your app is not visibly active to the user. If so, use a service as well.
By the way: A thread is not bound to a particular activity or service but to a process. If this process contains a running service then all threads in it are kept alive as well (except the process must be killed due to special circumstances).

Related

What is the best practice for always running networking android app?

I am implementing app that is going to be always running and connected to server.
So the tablet has nothing to do other than running this app, and checking the server all the time for updates to show on the screen.
What can be the best practice to keep the app always running and connected?
In my experience, i have 2 options to solve this problem:
Service always running and connected to my activity to keep it updated.
Keep the work in threads within the activity, since the activity will stay always on. The app will be always on.
My questions are:
What is the best practice for keeping the app running all?
What is the best practice to keep the app connected ? Threads within activity? or service connected to activity?
Is there any preferable structure for such application type?
thank you
Battery is something that i will always take into consideration especially when networking task has to be done. So analyze the point where the is absolute necessary to connect to server.
Whenever you server needs to contact the device use GCM push notification that will save your battery juice which you will spend in polling the server
Well for
Service v/s Thread
is concern the use service in which you should spawn worker threads which will perfrom the networking task
these threads will notify the main service thread when they are done for that you need to user Handlers in android
i will favor service over thread because if you close the activity network request will still be fulfilled once request is complete save it in some storage form(database/share pref/content provider) and retrieve it from them. Once you are done dont for get to destroy the service by all stopSelf a appropriate point or else the service will keep exhausting you phone resource. which will make you app a bad citizen.
A simple implementation of the about pattern i mentioned is IntentService which will automatically spawn the worker thread i.e you just have to override handleIntent method and do all the heavily lifting there which will not be on main thread. And IntentService kills it self when if finds itself doing nothings
The question which you have asked to my understanding is related to syncing with server you can find more about in from android docs
http://developer.android.com/training/building-connectivity.html
If you read the official docu from Android. The best solution is using a service for your kind of app. It's prepared to run continuosly in background. You can implement it to check the network in a transparent way and you can bind the information to another activity. Furthermore, it's more scalable if later you want to change your connection or requirements (it won't affect to your apps activities).
EDIT.
The good point is, that if someday for a reason your app is not in foreground. The service can still be running. Services are prepared for long running tasks http://developer.android.com/guide/components/services.html

Good Design: Worker Threads and Activity Restarts

It is well known that Android places our application components (Activities, Services) under threat of being killed at any moment. This makes things really complicated if you want to provide a robust, non-leaky solution, while at the same time keeping the code clean and addressing separation of concerns.
Problem:
An activity starts a time-consuming task (in form of a Runnable, AsyncTask or whichever other mechanism). A progress dialog should be displayed. The task will open several connections, but it should have a means of updating a progress bar, and it might need to display a choice dialog half-way to completion. It also should be able to close the dialog and show a Toast when an error occurs, or when it completes.
When an Activity is killed and later a new instance is recreated, I can think of two options:
Try to kill the running task as well, and spawn another task instance when a new substitute activity instance is created. This is not an option for a long running task, as it is unacceptable from a user point of view to start the task and see the progress bar indicator going from 80% back to 0% with no apparent reason. This however is the approach followed in the Shelves example by Romain Guy. Apparently this is the approach recommended in the official Developer Guide.
Keep the task running: So we could have an activity subscribing to (and possibly starting) the task for updates at onResume, and unsubscribing (and possibly pausing) it at onPause.
Following the second option means that we should prevent the task of being collected in case the activity is temporarily destroyed. For instance, we could declare it inside a custom Application class, or even offer it as a service to the rest of the application (using a Singleton? an Android Service?) I'm no fan of this, though, since the task is used only by the activity, so it doesn't make sense to make it available to other classes. Android Services on the other hand also have to deal with life cycle.
Option #2 also involves ensuring the old activity is not leaked. We should not try to update the GUI if no activity is present. The whole think should be thread-safe. Finally the task should not remain in memory after we are sure it is no longer needed. But at the same time, if the initial activity is destroyed, the task keeps running, and a new substitute activity kicks in, the task has to be around to update the GUI immediately and display the task current status (or result in case it completed).
The fact that the task might be running when no activity is shown is another problem to deal with, since we could need user interaction (choice dialog) synchronously at some point. This could be solved if the activity had the ability to immediately pause the task when reaching onPause, but the task could take some time to pause itself or even be unable to do so.
I know similar questions has been asked before, but I'm not asking specifically about how to solve the problem, but about what design would be recommended in order to achieve loose coupling and isolate the activity from the task as much as possible.
In short:
- This is a recurring problem in Android development and someone has probably come up with a clever design before. Is there a design pattern, or a well tested library that simplifies this?
- If you were to implement #2, which class would you choose to for the task (Runnable, Service, etc) and how would it communicate with the activity?
P.S. Please refrain from posting solutions based on the "orientation | keyboardHidden" hack XD. Other than this, any help would be appreciated.
UPDATE:
My first attempt has got a bit messy. The app is a bluetooth printing utility, which involves Detecting BT status (and asking the user to enable it if it were disabled), retrieving paired devices (and asking the user to pick one if there were more than one), then sending the data and finally inform the user about the result. As this task was 80% IO code, 20% GUI-related operations, I had to group the GUI code at the beginning and end of the task, then moving it out of the task back to the activity. I have an IntentService that does the heavy lifting, then reports back to the activity via BroadcastReceiver. This solves most of the problems but there are a few issues with such a design. First, there are all those constant strings used as keys to put and retrieve fields from the input and output Intents, which are introducing semantic coupling. I'd have preferred type-safety in the activity<->service communication. And I yet have to solve how to pass complex custom objects to the service in the Intent, by now I'm stuck with Parcelables and primitive parameters. Finally, both the activity and the service are using the same API (bluetooth), I'd have preferred to have al the BT-related code in a single class. I think I'll throw away this design, and try again with a custom printing queue based on threads, despite it will make harder dealing with killed activities.
why not have your activity start a service to host the long running task? a service is your best-bet for keeping things running long term. you can provide hints to the OS to leave it running. see startForeground() and START_STICKY.
you can communicate back to the activity by broadcasting from the service. have your activity programmatically register a broadcast receiver to listen for those intents. if the activity is paused, unregister your receiver, that way you won't respond when when you aren't in the foreground.
if the OS destroys your service, then it's killing the process, so your task is doomed anyway. the best you can do is restart it. anyway, this won't happen except in the most extreme conditions if you consider the above.
EDIT: summarizing some thoughts captured in the comments ... keeping a long running worker processe and automatically restarting it is almost always the wrong thing to do. mobile devices do not have the power source to make this feasible. the author stated this he has a special condition that negates this concern ... that would only be true if the device is connected to a power source almost always.
the android model is to provide a robust set of intents (notifications) to which your application can listen. these intents wake up your device / application when it's time to do something. your app should handle the notification, and then allow the device to go back to sleep immediately.
if there's no stock intent that maps to your event, you can use Google Cloud Messaging to wake up devices from a server. in other words, let the long-running processes run on the server, and wake up the device when required.
if you can do that, an alternative would be to use AlarmManager to wake up periodically and check some state. even if you did this frequently (e.g., every 5 minutes, which is also a no-no), it'd be much better than keeping the device awake always as is being suggested. also, make use of inexact wakeup intervals (see documentation linked above).

Android Design : How to run 3 different threads in Background for monitoring 3 different devices

I have an application, where I want to monitor 3 Bluetooth devices for their status from the Android Phone. For this, I need to send some data to each device and check if their response is correct every 5 seconds. And I want this processing to happen even when the application is not in Foreground. I thought of different solutions But I could not come up with any good solution.
I thought of using IntentService. But IntentService uses one thread for doing all the processing. But I would like 3 different threads because 5 seconds between every check is low that I cannot hop between checking devices in a single thread.
I thought of using 3 different IntentServices. But Not sure, if its the best way to go ?
I thought of using a Service and spawning of 3 threads, one foreach device. But I was not sure if these threads will run when the app is not in foreground.
What would be the best design to run this sort of app which does background processing in a app even when the app is not in Foreground and it has to run 3 different threads.
One Service, three Threads is what you want. Having a single thread performing I/O on multiple devices just seems like asking for problems, its creating a dependencies that are unnecessary. All Threads execute, regardless of whether the app is foreground or background.
The Android framework doesn't have any way to stop a Thread from running. Thread execution is managed by Dalvik. The framework stops delivering events to an app's main Thread when its in the background (other than events like BroadcastIntents), but it doesn't tell Dalvik to pause all threads in that process. This would kind of defeat the purpose of background processing if it did.
You don't necessarily need three threads. You definitely need three BluetoothSocket s. You might be able to pull it off just by having one Service that starts a thread from onStartCommand() and kills it in onDestroy(). The thread should loop and check if there is an active connection to each device, and if there isn't one, it should attempt to reconnect. Once a connection is established, it should write to and then read from the device, according to its protocol. There is nothing stopping you from writing/reading to multiple devices in the same thread. You can use nonblocking IO for this, checking whether there are bytes to read on each iteration until you find them, and then taking an action based on what you receive.
As far as pairing/bonding goes, I would do that outside of the thread that checks the devices, as you might want to direct the user to enter the pin/pair the device. Just make the background thread read/write to each of the three devices. You may find that you want multiple threads, it's purely a matter of taste... Only one thread is needed.

How do I organize this Android app with network i/o and multiple activities?

To begin with, this is the first Android app I'm writing, and I have very little prior Java experience. So nothing is too simple -- I could easily be missing anything "obvious".
Here's the general design I'm dealing with:
A long-lived bidirectional network connection.
Requests should go out over the network when the user interacts with the UI.
The UI should be updated when the responses to said requests come back -- asynchronously.
The app will contain multiple activities.
These activities will be focused on particular areas of functionality available, all relying upon the same underlying network connection. So I want to set up this connection no matter which activity my app starts in, and have it survive across switching to another activity in my app, but I want to shut it down when switching away from my app completely.
I think I want threads. I've got something basic working, but not well because I don't think I have them organized properly. I also am, so far, unable to pass data between the UI and network thread, so I can't get requests in nor actions for responses out. So I'd appreciate any advice.
I think I want threads.
You don't have a choice on that front. You will need a thread that listens on your socket for incoming data. Android is no different than standard Java in that respect.
I also am, so far, unable to pass data between the UI and network thread, so I can't get requests in nor actions for responses out.
Well, your thread should be managed by a Service. The network connection supports multiple activities, so no one activity should own the thread.
You will then need to decide when the network connection should exist. Since activities come and go, you will need to decide if the network connection should only exist when one of your activities is in the foreground (in which case you would likely bind to the service with bindService() from each activity), or whether there is an explicit "start" and "stop" operation that the user must do, so the connection can live after all of your activities are gone (in which case you would likely use startService() instead of bindService()).
Once you know when and how you are starting/stopping the service, you can decide how that service will communicate its results back to the various activities. There are tons of options, some better than others depending on your use case. Registered listeners, Messenger, broadcast Intents, a ContentProvider, and so on are all candidates. Any of those can be used by a background thread and can arrange to get data to the foreground activity on the main application thread. The other activities would typically refresh their data during onResume(), since there usually is no point in proactively updating them when they are not on the screen or may have even been kicked out of RAM.
IOW, "advice" is several chapters in a book or two. :-)

Should I do work in a separate thread if my android app has no UI?

My application is essentially a service that is started on boot (by a boot-completed receiver), and should periodically gather data, send it over the network, and go to sleep (probably using AlarmManager). It has no activities - no UI whatsoever.
Is there any reason to spawn an additional thread to perform the application logic?
if not, where should I perform the logic? in the OnStart method?
Is there any reason to spawn an additional thread to perform the application logic?
Absolutely. Your service will be killed off if it fails to respond within 5-10 seconds. Nothing can tie up the main application thread for that length of time.
I recommend an IntentService for use with AlarmManager. In particular, if you want the device to stay awake while you are doing whatever it is you are doing, you might consider my WakefulIntentService.
Also, regarding "no UI whatsoever", if you plan on distributing this app via the Android Market, please bear in mind that users seem to dislike applications with no UI. They install it, get confused when there is no icon in the launcher, and give you a one-star rating. Even if you do not need a UI for actual operation, you might consider at least having some activity in the launcher, that shows documentation, perhaps a log of work being done, allows adjustment to the frequency of your work, etc.

Categories

Resources