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/).
Related
I am pretty new to rxjava and just started learning it and converting our android project to rx.
So I wrote observables and chained them using flatmaps to call apis and return an observable. Now in the main activity I subscribe to them and add my UI code to onNext, onSubscribe, onComplete and onError as applicable.
But I have mutiple apis for which I have created an observable for each api, but I want to have a wrapper over the observer with which I subscribe to them. It is mainly to execute a piece of code like logging onNext/onError calls and showing a progress status on onSubscribe and dismissing it on onComplete/onError etc.
How do I do this other than adding it each time or having a baseobserver and adding super.method each time (one may forget super.method hence this handling should be removed from activity code I guess)
The idea is to implement a BaseActivity where all other activities extends from it. In this activity, you declare your generic Observer and when extending from this class, you get that Observer and you can make your own modifications depending on your needs. Take a look at this code
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.
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 :)
I am currently working on an android app just for personal use. The app communicates with a server by TCP sockets. If the user makes an input it needs to be sent immediately. Also there can be messages from the server at any given time which need to be shown on the UI. For all the networking stuff I have a background thread in mind.
Since I need to pass messages From the UI to the networking thread at any user input and also messages from the networking thread to the UI at any given time my question follows: How can I pass the messages? I already read about the Handler class for 3hours and I couldn't figure out anything. How do handlers work? What would be a neat and smooth running implementation of that? I look more for a strategy to accomplish this goal, not necessarily implementation details.
Thank you so much in advance!
http://developer.android.com/reference/android/os/AsyncTask.html Use this I too had a lot of problems with handlers but the async task handles all that annoying work for you. Make sure you use onPrexecute() and onPostExecute() to update the UI. Hope this helps.
You can use AsyncTask in this case.
You can call it on the UI thread and in onPostExecute do what you want to do with the messages.
It is a much cleaner approach than doing all the dirty networking work there.
First, I'll say I'm learning this myself, but I've managed to get this exact setup working in a prototype. If anyone sees something that should be changed to work better in Android, by all means let me know.
Second, I'm using empty messages so that we have code that would actually work. I assume that creating message objects is straight forward enough.
Part 1 - UI to Network Thread
As far as I have seen, Handler is the answer you need, but it's not the whole picture. Deucalion's comment about Looper is where you need to look next.
http://developer.android.com/reference/android/os/Looper.html
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
This setup is counter intuitive at first, you need to create the Handler object between the Looper.prepare() and Looper.loop() calls, inside your run() method. I don't know the magic behind the scenes, haven't had a chance to get that far down the rabbit hole.
Important Note:
The sample shows an anonymous Handler() being created. I highly recommend subclassing Handler in your own class and then using an instance of that. It's just a matter of reusability, a lot of network code ends up being the same.
So, rename LooperThread to NetworkThread, or whatever you'd like it to be, and put your connection code in the run() method, but outside the Looper.prepare() / Looper.loop() block (again I don't know how the magic works, so I'm just assuming this is better to do than to have it inside).
// process incoming messages here
Tends to look like this:
switch(msg.what)
{
case 1:
break;
default:
break
}
The LooperThread example has public Handler mHandler; but I prefer to make the handler private and create a method to return it. I do this just to prevent the handler from being accessible until after the network connection is established. No connection, nothing to do with the messages.
So, somewhere in your activity code you create the NetworkThread object, run it, and then get the Handler from it.
NetworkThread network = new NetworkThread();
new Thread(network).run();
//Handler networkHandler = network.handler;
Handler networkHandler = network.getHandler();
Then you just send messages to that handler as needed.
networkHandler.sendEmptyMessage(1);
Part 2 - Network Thread to UI
There are a couple of different ways to handle this. You can create a handler inside the Activity class. All activities have a Looper already setup, so calling Looper.prepare and Looper.loop seem to cause problems.
In my code I create a handler in the onCreate() method, and then I pass it into my NetworkThread object. There may be better places to create this Handler, I don't know what will happen if your application is suspended and then started again later with onResume() or onRestart()
public NetworkThread(Handler mainHandler)
{
this.mainHandler = mainHandler;
}
Then anywhere else I need to send a message to the UI:
this.mainHandler.sendEmptyMessage(1);
I prefer this method because the Handler code, that does the actual work, either exists in the classes the actually respond to the message (using the anonymous Handler objects) or in Handler subclasses that may be in the same package.
You could also pass in the Activity or a View to the network thread and from that call runOnUIThread(Runnable), but that requires you pass in a Runnable. So the code that is meant to work on the UI is being written or referenced in the Networking classes.
Update
You could also use a Service for this. The method above works when the Activity and the Networking have the same life span. If we only need network connection while the Activity is active.
If you need network connectivity beyond the life of the Activity, in a music streaming app for example, then going with a Service would be a better choice. It didn't seem like this was specifically what you were looking for the question.
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