LiveData vs Handler and LocalBroadcast - java

I have old Android/java code, that contains two derives from IntentService,
and these services not run in separate processes.
The question is about the way to return result from these IntentService.
One service return result by using Handler + Runnable, to run code in main loop:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
MyApplication.get().setFoo(someThing);
}
});
the other one is uses LocalBroadcastManager.getInstance(this).sendBroadcast(in); to send message to Activity, and Activity subscribe via BroadcastReceiver on message in onResume, and unsubscribe in onPause.
Am I right, and in both case it is possible to use LiveData to simplify things?
IntentService should create LiveData and who want result should observe it,
and when new data arrives IntentService should call postValue,
or may be there are some reefs to prevent usage of LiveData here?

I think that LiveData will not help you in sending any data from Service to other components.
The problem with communication from any Service to other components is that you don't usually obtain a direct reference to the Service, therefore you can't directly "subscribe" to notifications.
Theoretically, if the Service runs in the same process, you can bind it, obtain a reference to Service object and then directly perform subscription. However, this is often an overkill and I don't see this pattern being used widely.
In your examples, there are two communication mechanisms:
Service reaches statically to Application object and sets some data. This is a communication through global state, and is generally considered an anti-pattern.
Communication through LocalBroadcastManager
From the above two mechanisms, I would use only #2 and avoid #1 at all costs.
Back to LiveData.
In order to be able to get LiveData object from the Service you will need to have a reference to that Service. This is usually impossible unless you bind Service in the same process, or use some ugly hack that involves global state.
Therefore, usefulness of LiveData in this context is very limited.
By the way, while LocalBroadcastManager is alright, I find this mechanism too complicated and restricting. Therefore, if the Service runs in the same process, I prefer to use EventBus in order to communicate from Service to other components (or vice-versa).
An example of such a communication you can see in SQLite benchmarking application that I wrote several days ago. In this app, TestService posts status changes and test results to EventBus as sticky events, and TestActivity subscribes to those events.

Both methods work with using LiveData since the purpose of LiveData is to have it on another thread and still notify users when something has changed. Seems like it would definitely replace LocalBroadcastManager.getInstance(this).sendBroadcast(in); and your IntentService would postValue. Just have your activity or anything that needs to be aware of the changes become an observer.

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.

Android callback listener - send value from pojo in SDK to an application's activity

I have a java class buried deep in an SDK that performs an action and returns a boolean. It has no knowledge of the application's main activity, but I need the main activity to receive that boolean value.
I've seen a lot of questions regarding callbacks, broadcasts, and listeners but they all seem to have knowledge of the activity. My pojo does have an activityContext but I don't know how to get the value back to the application's main activity.
I'm already using an AsyncTask in my pojo and I'm trying to figure out how to send the boolean in the onPostExecute method in a way that the application's main activity can receive it.
Does anybody know how to do this?
I'd suggest using a message bus or observable/observer pattern.
Square has Otto a nice little open-source library that implements a message bus.
Observer pattern is well described at wikipedia for example.
Either way what you will have to do is essentially start listening to either your POJO if you make it Observable, or subscribe for bus events in onResume() (or onStart()) and stop listening in onPause() in your activity.
BUS
I like bus more because of it's loose coupling and the fact that you can send any arbitrary POJOs to the bus and only listen to one specific type for example.
so you post a message this:
bus.post(new SomethingICareAbout("I really really do"));
and elsewhere in your codebase (in your case in the activity):
#Subscribe
public void onSomethingIcareAbout(SomethingICareAbout thingsAndStuff) {
// TODO: React to the event somehow. Use what you received.
}
#Subscribe
public void onSomethingElseIcareAbout(SomethingElseICareAbout otherThings) {
// TODO: React to the event somehow. Use what you received.
}
The above is intentionally simplified, you still need to create the bus and subscribe to it, but you will find that in the docs :P
Also it uses annotations and is really lightweight (codewise).
Observer / Observable
Observer/Observable on the other had is part of Java, so it's built in. But it is tightly coupled, your activity will have to implement Observer, your POJO will implement Observable and you willl have to implement update() method in your Activity, this one will get all the updates no matter what you send by the Observable.
I hope this makes sense a bit :)

Is there a reason to use the Observer pattern over a Broadcast Receiver?

Recently, I have started working on an Android Project that stopped using Broadcast Receiver's in favor of "Listeners". Really, this implementation is using an observer pattern similar to this article (in my case, there is even .aidl involved).
What I am failing to understand is why. I have been taught that composition is better than inheritance. To me, a broadcast receiver is composition. It is a native Android feature, that everyone Android developer should be familiar with. So why, is there any reason that I should drop my Broadcast Receivers in favor of an observer pattern? Is this just a product of bad design on my teams part?
Update:
I did find a comment stating that this is to follow Single Responsiblity, however I am not sure I follow as any class implementing a listener is bound to have other responsibilties (for instance, activities, who are managing the UI lifecycle).
Using BroadcastReceivers allows to decouple one component from another. A sender doesn't know anything about receivers of his message. It just sends broadcasts and doesn't care if it was received and handled. The same concept has an event bus (for example Otto). But global BroadcastReceivers have a small overhead because they are by their nature a cross-application facility. So if you need to send events only inside one application I would use LocalBroadcastManager or the event bus that I've pointed previously.
In case of using listeners (observers) components become tightly coupled because sender has a reference to the receiver and know about it's nature (what interface a listener implements) and must check if the listener is not null.
Yes, I have seen 100 times that BroadcastReceiver uses the Observer design pattern, but still keenly disagree with this.
First of all the definition of the Observer design pattern is :"The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their method". What object is observed in the BroadcastReceiver?
The ctx.registerReceiver(receiver, filter) does not provide information about any object. Broadcast receiver in its idea is not dedicated to notify number of classes about changes in any object- it is simply listener of broadcast mechanism, but not only. In order to get notification about changes, you must register a receiver object with filters. You will get NO NOTIFICATION once you did not set a filters with receivers. So your receivers should be selected regarding intent's action in order to your onReceive(Intent,...) will be triggered. At least I see here the selector pattern. But not only it. What really broadcast is doing? It propagates intents have been sent like a hub and selects registered receivers by filters of action. Now see the definition of the mediator pattern(https://sourcemaking.com/design_patterns/mediator). Is not the case? The broadcast mechanism implements skills enabling object interaction, where sender does know nothing about listener and listener says what it is to be listened regardless who has sent.Is it not mediator
Basically, BroadcastReceiver is indivisible part of the Broadcast mechanism of Android. Separation of BroadcastReceiver from the whole mechanism is simply not correct.From It is like JMS message consumer is indivisible part of JMS.
Intent, used in broadcast receiver is dedicated to transmit action and bundle of arguments(parameters, what else). It is used normally to transfer an action(!) with data. Really, it is data object for command.
For comparison, let us consider the really well known case of Observer pattern in Android is ContentObserver. How it works:
getContentResolver(). registerContentObserver( SOME_URI,true, yourObserver); See, listener is attached to dedicated resource, not for general purpose listening. It is triggered once content changed (do you sent a notification about anything????) and notifies what is changed(Uri). Yes, this is THE OBSERVER really. It notifies about object changed and listener-observer sees what is changed in observed object. Is it the model of work of Broadcast????
In broadcast I see elements as least of mediator, selector and DTO.

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.

Event handling in multithreaded application

I'm designing a stand-alone, multi-threaded application in Java.
I'm trying to choose the best event-handling solution for his project.
I have 1-3 threads generating events (e.g comm thread completes file upload), while other threads might want to be registered for notification on this event.
I want the event-generating and event listening to be as uncoupled as possible.
What do you suggest?
Use an event bus.
An event bus can be thought of as a
replacement for the observer pattern,
where in the observer pattern, each
component is observing an observable
directly. In the event bus pattern,
each component simply subscribes to
the event bus and waits for its event
notification methods to be invoked
when interesting events have occurred.
In this way, an event bus can be
thought of like the observer pattern
with an extra layer of decoupling.
Here's a nice presentation about using an event bus ins GWT. It should give you a good idea about the benefits (and it's quite funny, too).
EDIT
The first link is mainly given as an example. It's really not that hard implementing something similar on your own which fits your needs.
I would use ExecutorServices to manage your thread pools. This way when you have a listener to an event, you can ensure the event is added to the right service either using a Proxy, or hande coded. e.g.
public void onEventOne(final Type parameter) {
executorService.submit(new Runnable() {
public void run() {
wrappedListener.onEventOne(parameter);
}
}
}
You can pass this listener wrapper as and be sure the event will be processed using the desired thread pool.
Using a Proxy allows you to avoid this type of boiler plate code. ;)
Do you really need a solution where each thread can register as a listener for each type of event? If so, use an event bus type solution (or a centralized observable with typed events).
If you don't need this flexibility a manager-worker setup could suffice, where the manager gets notified of events (like: "I'm finished with my job") and can fire up workers as needed.
Usage of an event bus is definitely the right choise. There are various solutions out there. You can also check out MBassador https://github.com/bennidi/mbassador.
It is annotation driven, very light-weight and uses weak references (thus easy to integrate in environments where objects lifecycle management is done by a framework like spring or guice or somethign). It provides an object filtering mechanism and synchronous or asynchronous dispatch/message handling. And it's very fast!
Google Guava has an event bus as well but it uses strong references which can be a pain if you do not have full control over your object lifecycle (e.g. spring environment)
EDIT: I created a performance and feature comparison for a selection of available event bus implementations including Guava, MBassador and some more. The results are quite interesting. Check it out here
http://codeblock.engio.net/?p=37
use command design pattern to decoupling

Categories