Android Async, interfaces, and onComplete() for handling responses in GUI - java

I have a utility class that will be running an async task using HTTP. On complete I've setup an interface so I can just fire off methods to process the results (whether it's an activity, fragment, etc.). This way as long as I implement the interface I can always pass 'this' from wherever I am and it will call the standard onComplete() method to process results when they're available.
My issue is that in most cases I just need one HTTP call so it's straight forward. What about when I need to do 1,2,3,N HTTP calls in a fragment let's say what will happen when they all complete and go to fire the onComplete() method I set up?
Will the OS queue everything up properly since it's now the main GUI thread and I just have to keep track of a simple counter like numTasks = 0, and each time onComplete() fires just increment so I know when all tasks are done?
And also how do I know which call is completing to handle the different responses accordingly? I could get back something different from each and need to process accordingly in the same onComplete() method right? In PHP you can check who called you, is there a way to do that in Java and somehow distinguish between the different instances of the async subclass object I created? Each time I create this object I'll be storing it as a variable, it'll do it's async stuff, than the onComplete() gets fired from within it for the callback.
Fragment <--implements interface for onComplete()
-instance 1 (implements async) <--pass 'this' as callback
-instance 2 (implements async) <--pass 'this' as callback
-onComplete() <---fired from within instance 1 & instance 2 during postExecute()
-increment task counter++ to know when we're done, but how to differentiate which instance completed and called me to handle response properly?
Thanks.

The interface is just a conduit through which Java passes information. Assume that your Fragment class passes its context to your utility class:
new Async().executeHTTP(this);
In the utility class:
public class Async {
public void executeHTTP(Context context){
...
((YourInterface)context).onComplete();
}
}
Because you're using the context from your fragment instance, the onComplete() method is only called for that particular instance. The interface creates a conduit between the interface caller and the interface implementation. (In this case, Async instance->Fragment instance.)
If you want to differentiate between different calls from the same instance, just pass in an identifier and pass it back through your onComplete method.
new Async().executeHTTP(this, ++requestID);
...and in the utility class:
public class Async {
public void executeHTTP(Context context, int id){
...
((YourInterface)context).onComplete(id);
}
}

Related

LiveData vs Handler and LocalBroadcast

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.

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 :)

Best approach to writing a network class

I want to write a class that handles all my network interaction called NetworkManager. So using an instance of this class I'd have something like:
NetworkManager nm = new NetworkManager();
...
nm.login(username, password);
...
However, what is the best approach so this network manager can do something on the UI thread once some response has been received? Modelling on a onClick style event I think this would be like:
nm.getPicture(new NetworkListener() {
#Override
public void run(Picture p){
updateUI(p);
}
Where I am unsure how to write the getPicture method and the NetworkListener() class.
I don't want to use AsyncTask, because this would mean I'd have to write the server code at different parts of the MainActivity. I have also considered a broadcaster and a listener, but this seems too much for a one off event.
Checkout Retrofit (http://square.github.io/retrofit/) it might be useful to consider for integrating the part of your network class. I'm not sure if you will have multiple similar calls, but if so, I would advice you to apply the Observer pattern, where you make the call and wait for the response asynchronously, yet, there's a nice library to accomplish that, very well documented, called Otto (http://square.github.io/otto/).

What is callback in Android? [duplicate]

This question already has answers here:
Callback in Android?
(3 answers)
Closed 9 years ago.
I want to understand the concept of callback. I have searched on internet about the callbacks and there are many examples using interface, and one class is calling a method of another class using that interface. But still I can't get the main concept of callbacks, what is the purpose of using callbacks?
Here is a nice tutorial, which describes callbacks and the use-case well.
The concept of callbacks is to inform a class synchronous / asynchronous if some work in another class is done. Some call it the Hollywood principle: "Don't call us we call you".
Here's a example:
class A implements ICallback {
MyObject o;
B b = new B(this, someParameter);
#Override
public void callback(MyObject o){
this.o = o;
}
}
class B {
ICallback ic;
B(ICallback ic, someParameter){
this.ic = ic;
}
new Thread(new Runnable(){
public void run(){
// some calculation
ic.callback(myObject)
}
}).start();
}
interface ICallback{
public void callback(MyObject o);
}
Class A calls Class B to get some work done in a Thread. If the Thread finished the work, it will inform Class A over the callback and provide the results. So there is no need for polling or something. You will get the results as soon as they are available.
In Android Callbacks are used f.e. between Activities and Fragments. Because Fragments should be modular you can define a callback in the Fragment to call methods in the Activity.
You create an interface first, then define a method, which would act as a callback. In this example we would have two classes, one classA and another classB
Interface:
public interface OnCustomEventListener{
public void onEvent(); //method, which can have parameters
}
the listener itself in classB (we only set the listener in classB)
private OnCustomEventListener mListener; //listener field
//setting the listener
public void setCustomEventListener(OnCustomEventListener eventListener) {
this.mListener=eventListener;
}
in classA, how we start listening for whatever classB has to tell
classB.setCustomEventListener(new OnCustomEventListener(){
public void onEvent(){
//do whatever you want to do when the event is performed.
}
});
how do we trigger an event from classB (for example on button pressed)
if(this.mListener!=null){
this.mListener.onEvent();
}
P.S. Your custom listener may have as many parameters as you want
Source
Callback can be very helpful in Java.
Using Callback you can notify another Class of an asynchronous action that has completed with success or error.
CallBack Interface are used for Fragment to Fragment communication in android.
Refer here for your understanding.
It was discussed before here.
In computer programming, a callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time. The invocation may be immediate as in a synchronous callback or it might happen at later time, as in an asynchronous callback.
I am using in the following case:
In UI I got an action from a button, for eg. the user want to download an 500mb file.
Thank I will initialize the background engine (AsyncTask class) and pass parameters to him.
On the UI I will show a blocking progress dialog and disable the user to make any other clicks. The question is: when to remove the blocking from UI? the answer is: when the engine finished with success or fail, and that can be with callbacks or notifications.
What is the difference between notification and callbacks it is another question, but 1:1 is faster the callback.

Implementing Synchronous network call in java waiting for an ack message?

How would you go about implementing the equivellent of a wait until complete method call in Java?
Basically what I want to do is hava a method that sends a message over the network to a server application and waits till it gets the appropriate Ack message from the server with either an operation completed successfully or operation failed and an error message.
I already have a non blocking version of my method which passes a callback class in which has a method that is called on callback.
would it make sense to construct a callback class pass it in to my previous method and then perform a wait operation and on the callback have that class do a notify?
Adding a .wait() to your callback class would be the easiest path. It can sit there spinning on some flag until your callback switches it, just be sure to include Thread.yield() or .sleep() in your loop.
Saves having to rewrite an alternative blocking comms channel.
Short answer: Yes. I'm a fan of using what's in the class library already, what you describe sounds a lot like an Observer pattern, for which you have the Observer/Observable interfaces already, assuming you're using J2SE.
EDIT: Something was wrong with my coffee :) Obviously, what I meant to say was check out what's in java.util.concurrent package, specifically the Future<> and ExecutorService classes.
Yes, use your existing method like you are suggesting. Create the callback in your sync method call that will coordinate with the sync method call via wait()/notify(). The sync method will call the async one and then wait(). When the callback is called, it will call notify() to wake up the sync method so it can return the results.
Please ignore if you're not using JMS.
If you are using JMS, then you could use a QueueRequestor, which is an implementation of the Request Reply integration pattern.
That is, the following call appears synchronous to the client, even though asynchronous messages are used:
QueueRequestor requestor = null;
try {
requestor = new QueueRequestor(session, queue);
Message response = requestor.send(request);
} finally {
if (requestor == null) {
try {
requestor.close();
} catch (JMSException e) {
// log error message
}
}
}

Categories