What's the right design approach for an application level thread? - java

I am developing a Multiplayer Online word game on Android and would like to implement a thread that checks for server side events like the following:
Player join a game.
Player left a game.
Player won a game.
etc...
The thread will be responsible for listening for all kinds of events and dispatching events to the responsible activity If it's visible to the user.
In other words to be more clear, I've got a list of event and each activity must register to a subset of these events.
Events:
E1 - E2 - E3 - E4
Activities:
Activity 1 interested in E1 and E2.
Activity 2 interested in E1, E2 and E3.
Activity 3 interested in E3 and E4.
I am asking about the best design approach to implement a thread that runs in the background and can dispatch events to all activities?
Some Ideas:
-Implement an AsyncTask on the application level.
-Send broadcast intents to a custom actions.
-A service is not the best approach because it should be created to run in the background when the user is not interacting with your application.
Can you propose a best practice approach?

A good approach for this is to use a Service combined with AsyncTasks.
While a Service is useful while the user is not interacting with your application, that certainly isn't its only use. A Service is the logical home of anything that does not require a UI.
In data driven apps, I have used Services as API adapter layers. It is nice because I can launch it from any activity without worrying about whether it is already instantiated or whether I need to do any cleanup work after I'm done. The framework manages the service's lifecycle and tracks clients.
I think your case is similar. Each activity can use bindService and unbindService to register for updates as long as it needs. The service will continue to do its thing as long as any Activity is bound. The service can keep track of which activities need updates using the Intents received in onBind and onUnbind, and send them updates via specific Intents, or, more appropriately, the service can fire broadcast intents and the Activities can register for what they need.
Within the Service, you would run AsyncTasks (probably running them on AsyncTask.THREAD_POOL_EXECUTOR so you get more than one thread) to do your updates. Remember that the service itself is launched on the UI thread.
Another nice benefit to using a service is that it doesn't require an Activity to run. One use for this that comes to mind is post-shutdown cleanup. If you need to post scores or analytics or something when the user exits, you can allow the activity to close quickly and finish the longer-running work in the background.
Activities can request those longer individual tasks from the Service using startService, and the service won't exit until it calls stopSelf (or stopSelfResult).
The combination of start/stop and bind/unbind really allows for clean management of the service. It will run when and only when it needs to, and you can keep all your API access in one place.
Edit:
As if this wasn't a stout enough wall of text, I've come up with another good reason to use a Service. From the developer guide on processes & threads:
Because a process running a service is ranked higher than a process
with background activities, an activity that initiates a long-running
operation might do well to start a service for that operation, rather
than simply create a worker thread—particularly if the operation will
likely outlast the activity...

Related

How should the data from long running operations be passed to the fragment to be shown in UI?

I am new to Android and I have a kind of design question. So I understand that it is recommended to use Fragments. I also understand that an Activity "owns" a Fragment.
So my question is the following:
Assume we want to make a long running background call e.g. HTTP to a server.
The results should be displayed in the UI.
So what is the best/standard practice?
1) Should the object doing the long running calls be "owned" by the Activity and the results send back to the Activity and then from the Activity to the Fragment so that the UI is updated?
2) Or should the object doing the long running called be "owned" by the Fragment and the results are send back to the Fragment for the UI to be updated? So the Activity is completely unaware of this?
Neither, IMHO. The object doing the long running should be managed by a Service, where you are using WakeLock (and, if needed, WifiLock) while the long-running HTTP operation is running. An IntentService might be a good candidate, as you need a background thread anyway.
The service, in turn, can use some sort of in-process event bus (LocalBroadcastManager, greenrobot's EventBus, Square's Otto, etc.), to let the UI layer know about any significant events that occurred from that HTTP operation. Whether the activity or the fragment is the one to subscribe to the events on the bus depends on what needs to happen for the event. If a fragment's widgets need to be updated, the fragment would subscribe. If the mix of fragments change, or some other activity-level UI change is needed, the activity would subscribe.
All of this assumes that by "long running" you mean something taking over a second or so.
For the long running task it's recommended to implement a sticky Service that contains a thread for the ServerSocket listener. Next I'd recommend to process requests by dedicated Thread's which are managed by a thread pool (check for instance this example).
In order to display results in your activity there are several approaches possible:
send a local broadcast from your service or thread which gets processed by registered BroadcastReceiver's which are part of your UI component (either Fragment's or Activity's)
bind your Service to the Activity (which might contain further fragments) and propagate information to containing fragments. There are three ways to go.
Note: In this post it's being said it's better to bind to the Application
pass data via Intent or a SQLiteDatabase
What I like and prefer is using local BroadcastReceiver's but this is just my personal preference.
It depends on your requirements, what might be the best solution.
I'm using a variation of the design recommended by #CommonsWare. I have an ApiClient class that listens to the event bus for requests to invoke API methods asynchronously. Any parameters that are needed for the API call go into the bus request message.
The ApiClient uses Retrofit to make the async API call, and posts a 'result message' containing the result to the event bus on success, and an 'error message' if there's an error. Each API call has it's own triplet of bus messages - xxxRequest, xxxResponse, xxxError.
So, when an Activity or a Fragment (or other, non-ui class) wants to invoke the api, it registers to the bus for the xxxResponse and xxxError messages, and then posts an xxxRequest message to the bus.
The only potential down-sides are:
The ApiClient is a singleton, and is owned by the Application class, just so that it doesn't get garbage collected.
You wind up with a large number of Message classes - I deal with this by putting them into their own package.

Fragments vs AsyncTask vs IntentService vs Longrunning operations

I have the following design:
Activity/FragmentA upon a user action starts an AsyncTask to fetch a set of data.
While the AsyncTask is running, a progress indicator is displayed to the user.
When the AsyncTask finishes its task and fetches the resultset, it saves it in a singleton class serving as a shared datamodel.
When FragmentA is notified that the AsyncTask has finished (LocalBroadcastReceiver) then it start ActivityB/FragmentB which takes the set of results from the shared singleton and displays them in a ListView.
This works but since I am a newbie in android I am trying to understand and learn best practices.
E.g. I see a small delay from the time the progress bar is dismissed to the time the UI of ActivityB/FragmentB is displayed (during this latency the UI of ActivityA/FragmentA is still visible).
Also I think that somehow if the fetch of the items was done from FragmentB instead of FragmentA would make FragmentB "autonomous"
Overall can someone please help me understand how could I have implemented this differently using better/standard practices in android and the pros/cons of each approach?
Fragments
Fragments are small part of the activity which has their own life cycle, which provides developer more flexibility to deal with UI. Fragments has nothing to do with background processes.
Now your main question is about the background processes.
AsyncTask
This is nothing but the bit better version of thread with some predefined callbacks, when u need to perform some network operation which will take not more than 20 seconds, and after that it refreshes the UI, its better to use asycntask. Do not use Services (Avoid complexity, Keep it simple). You can use some third party library also.
IntentService
Now IntentService are better version of service, the main purpose of IntentService is to avoid performing long running operations on mainthread and provide queueing system to the developer. You should use services if you do not need user interaction while running long running operations (e.g syncing app with the server at the end of every day).
So for conclusion
User Interaction + short running network operation = AsyncTask
No User Interaction + long running network operation = IntentService + Broadcast Receiver to notify UI of needed

Android service and asynctask communication

I have a problem trying to figure out the best way to complete a simple app following the Android best practises. Here is the scenario:
1) I have an activity where the user enters something, its then send to a background Service
2) The background service performs some checks on the input and spawns a new AsyncTask to process the input.
3) The asynctask updates a Status Hashmap in the service with its progress and status
4) There is an second activity that binds to the Service to display a list of currently running tasks from the service and their progresses. The idea is that even if this activity is closed the service will continue to run the tasks and when the activity is reopened the refreshed stats will be shown.
I have problems in 3 and 4. What is the best way to communicate to the Service from within the AsyncTask's onProgressUpdate method and at the same time update the listing activity if its opened, if its not opened its simpler, just update the service tracking maps and when the activity is opened it will read them and update.
Im not sure what is the standart approach to handle "Events" of that sort. Do you have to use a Broadcast listener and subscriber or its too much for this simple purpose?
If you want to communicate between the service and an activity, you could broadcast updates from the service within the AsyncTask.onProgressUpdate method (alternatively within the AsyncTask.onPostExecute(Result) method) and listen for the updates using a broadcast receiver within your activity.
Instead of me copying and pasting a lotta code, check out Vogella's tutorial on services, especially the exercise (7. Exercise: Using services and service communication), found here
www.vogella.com/tutorials/AndroidServices/article.html#tutorial_intentservice
Within the exercise, you're looking for the DownloadService.publishResults(...) method which sends out a broadcast from the service to whichever broadcastreceiver is listening for updates, and the use of the BroadcastReceiver in MainActivity, which handles the updates from the service.

Service Class in Android

What is the purpose with Service class?
Many examples with Bluetooth Low Energy uses Service classes for all Bluetooth communication, connecting, disconnecting, scanning for devices etc. Activity classes always call method from this Service class.
What about implementing all Bluetooth communication directly in an Activity class instead?. Why does nobody implement like that and uses a Service class instead?
From the documentation:
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.
Basically it is a loosly coupled component independet from activitys lifecylce. The problem is in Android you can't really control when an activity will be created/destroyed, so for example if you are loading somenthing in an activity and you receive a call, your activity might get destroyed and the result of your update will be lost, or even worst your loading task won't finish and holds on to the activity and it can't be garbage collected and you create a memory leak.
So you use service for long running background tasks, but you just let them run as long as you have to, to avoid, again, memory leaks and be nice to your resources.
Caution: It's important that your application stops its services when it's done working, to avoid wasting system resources and consuming battery power. If necessary, other components can stop the service by calling stopService(). Even if you enable binding for the service, you must always stop the service yourself if it ever received a call to onStartCommand().
what about implementing all Bluetooth communication directly in an Activity class instead
you most likely end being killed by the framework for doing too much on UI thread (aka ANR - Application Not Responding). See Keeping Your App Responsive article on develoer site.
Anything that is not directly related to UI (like networking of any kind) should be offloaded to separate task. Be it AsyncTask:
This class allows to perform background operations and publish results
on the UI thread without having to manipulate threads and/or handlers.
or IntentService:
IntentService is a base class for Services that handle asynchronous
requests (expressed as Intents) on demand.
. The Service (not IntentService) is for slightly different purpose:
A Service is an application component representing either an
application's desire to perform a longer-running operation while not
interacting with the user or to supply functionality for other
applications to use.
Service class is used to perform , background non UI operations like playing audio file.Further service is the component that will run in background even if your activity gets destroyed ,While using Bluetooth we really do some non UI phone level operation and hence we use Services .
Activity class isn't a good place for any kind of communication tasks. It can be killed as soon as user switches to another activity. It shows UI, that means that we can't do much work in Activity's thread. Sometimes you can use somthing like
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// do something here
}
});
t.start();
or more complicated things with AsyncTask but this is suitable for short-time actions.
Service will not be killed so fast, so it's good for background work of any kind. Just read Android documentation about services.

When to use a Service or AsyncTask or Handler?

Can someone tell me the TRUE difference?
My rule of thumb is that an AsyncTask is for when I want to do something tied to single Activity and a Service is for when I want to do something that will carry on after the Activity which started it is in the background.
So if I want to do a small bit of background processing in the Activity without tying up the UI I'll use an AsyncTask. I'll then use the default Handler from that Activity to pass messages back to ensure updates happen on the main thread. Processing the updates on the main thread has two benefits: UI updates happen correctly and you don't have to worry so much about synchronisation problems.
If for example, I wanted to do a download which might take a while I'd use a Service. So if I went to another Activity in my application or another application entirely my Service could keep running and keep downloading the file so it would be ready when I returned to my application. In this case I'd probably use a Status Bar Notification once the download was complete, so the user could choose to return to my application whenever was convenient for them.
What you'll find if you use an AsyncTask for a long-running process it may continue after you've navigated away from the Activity but:
If the Activity is in the background when your processing is complete you may have problems when you try to update the UI with the results etc.
A background Activity is far more likely to be killed by Android when it needs memory than a Service.
Use Service when you've got something that has to be running in the background for extended periods of time. It's not bound to any activity. The canonical example is a music player.
AsyncTask is great when some stuff has to be done in background while in the current activity. E.g. downloading, searching for text inside a file, etc.
Personally I use Handlers only to post changes to the UI thread. E.g. you do some computations in a background thread and post the result via handler.
The bottom line: in most cases, AsyncTask is what you need.
To complement the other answers here regarding the distinction between service and AsyncTask, it is also worth noting[0]:
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
Services tend to be things that describes a significant part of your application - rather than an AsyncTask which is typically contributes to an Activity and/or improves UI responsiveness. As well as improving code clarity Services can also be shared with other applications, providing clear interfaces between your app and the outside world.
Rather than a book I would say the developer guide has lots of good answers.
[0] Source: http://developer.android.com/reference/android/app/Service.html#WhatIsAService
AsyncTask: When I wish to do something without hanging the UI & reflect the changes in the UI.
E.g.: Downloading something on Button Click, remaining in the same activity & showing progress bar/seekbar to update the percentage downloaded. If the Activity enters the background, there are chances of conflict.
Service: When I wish to do something in the background that doesn’t need to update the UI, use a Service. It doesn’t care whether the Application is in the foreground or background.
E.g.: When any app downloaded from Android Market shows notification in the Status Bar & the UI returns to the previous page & lets you do other things.
Service
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with.
When to use?
Task with no UI, but shouldn’t be too long. Use threads within service for long tasks.
Long task in general.
Trigger: Call to method onStartService()
Triggered from: Any Thread
Runs on: Main thread of its hosting process. The service does not create its own thread and does not run in a separate process (unless you specify otherwise)
Limitations / Drawbacks: May block main thread
AsyncTask
AsyncTask enables the proper and easy use of the UI thread. This class allows performing background operations and publishing results on the UI thread without having to manipulate threads and/or handlers. An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread.
When to use?
Small task having to communicate with main thread
For tasks in parallel use multiple instances OR Executor
Disk-bound tasks that might take more than a few milliseconds
Trigger: Call to method execute()
Triggered from: Main Thread
Runs on: Worker thread. However, Main thread methods may be invoked in between to publish progress.
Limitations / Drawbacks:
One instance can only be executed once (hence cannot run in a loop)
Must be created and executed from the Main thread
Ref Link

Categories