Android: looper/handler vs. Java Observer? - java

Aren't these competitors? I'm thinkin they're not, but don't see it.
How about within the context of an Activity needing to learn when a Service has new xyz?
Thanks!

They are for different purpose so you can't compare in the way that one exclude the other as perhaps you may intend. I explain:
Registered Observers receive notification of a change all together sequentially simply calling once notifyObservers(..).
Handlers allow you to modify UI components from a background thread but you handle/update only 1 "observer" (the one handled by the Handler).
More advanced, if you think, you can even combine the two, to always be exception free while update UI from a background thread still keeping the Observer pattern.
I think nobody answered you in these 5 years because almost nobody is aware of great power of Observer pattern ;-)

Related

Is chaining AsyncTasks considered bad practice? [duplicate]

This question already has answers here:
Android AsyncTask - Order of execution
(6 answers)
Closed 7 years ago.
I'm writing an app that does the following:
Parses a webpage and extracts image URLs from it
Decodes them to Bitmap and shows them in an ImageView
I don't want these to run on the UI thread and obviously the 2nd point can't be performed without the 1st being completed.
Can i chain AsyncTasks to achieve this? I mean starting the second one from the first one's onPostExecute() method.
Is this considered bad practice? If so, how should i do this?
(this is a theoretical question, i'm not asking for code)
You can definitely do that and there is nothing wrong with chaining multiple AsyncTasks if you really have to. And I want to emphasise: only if you really have to.
AsyncTasks bring a certain overhead with them. If you chain two AsyncTasks you get twice the overhead. You don't want that. You should use the least amount of AsyncTasks possible.
In your case the solution actually seems quite simple: Perform all of the work in just one AsyncTask. Ask yourself: Is there really any need for two separate AsyncTasks? From your description it certainly doesn't seem like it. If you just use one AsyncTask your code will run a lot more efficiently than if you use two.
Please note that AsyncTasks should only be used for short operations that take a few seconds and which are started in response to a user action. If you need to perform some long running operation in the background than an AsyncTask is probably not the best solution. I can't really tell from your description if what you want to do is something suited for an AsyncTask or not, but if the work you are doing doesn't fall into the criteria I described above you are probably better of with an alternative solution.
Can i chain AsyncTasks to achieve this? I mean starting the second one
from the first one's onPostExecute() method
The only constraint is that the AsyncTask has to be instantiated on the UI Thread. As long as you instantiate it on the UI Thread you should be safe. So the answer is yes, you can do it.
If so, how should i do this?
There are different approaches to solve the same problem. You could use an ExecutorService for instance, and a Delegate/Listener, an Observer or a BroadcastReceiver to notify the completeness of a task
There's a good answer for this here but since you're asking theoretically, I'll tag an opinion onto the end of it.
From the AsyncTask docs:
AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.
Chaining of Futures (or Promises) is a perfectly normal asynchronous practice. Future A does something and returns a value; this value can then be consumed by another asynchronous chunk of code, and so on, forming a logical processing chain.
In pseudo-code, it looks like this:
Future( calculate and return x).map( consume x and return y)
.map ( consume y and so on)
Of course, you can. Theoretically, this logic you talked about above can't be wrong. But, you have to understand that: onPreExecute and onPostExecute are called on the Main Thread, namely the UI Thread while doInBackground on another non-main-thread. Meanwhile, if you executed the second AsyncTask on the doInBackground of the 1st one, onPreExecute and onPostExecute of the 2nd one wound not be run on the Main Thread. Take notice of that.
Well, I don't think it is bad practice. The only downside I can see is that code becomes a little more difficult to read, especially if you end up chaining a lot of callbacks.

Multithreaded Observer in Java - preserve proper order

I am implementing something that I would call "Observable Set". It is just a normal set, but it can have some observers that are notified about adding new elements.
What is important for me, is that elements may be added from many threads at time, and also there are many observing threads. I hold Observers in CopyOnWriteArrayList (it is thread-safe). The key point is to inform observers about adding elements in way, that informing order for each of observers is the same as order of adding elements.
What is best approach?
The most naive one is to put adding and informing in "synchronized" block. But i believe it can be slow etc.
Second I've tried was to just add element to set, and add it to "informing queue". With each addition of element it was checked whether informing is turned on. If not, it was started until the queue was empty. It was working quite OK but i was afraid that it wasn't nice approach.
The last that I've implemented, i would call as "informing threads". With adding observers, each observer has it's own "informing thread" created. That thread runs in background and checks if it's at end of global "informing queue". If it isn't it informs specific thread about new elements. However I've problems with synchronization, and while(true) loop. I don't know how to set condition to end thread. The next problem I noticed when writing it, is that every new thread will be informed from beginning... It's not good.
I hope I have described everything quite well. If not, please let me know, i will try to fix it.
What is best way to accomplish this task?
Thanks!
Your second solution could be improved to use a BlockingQueue: with it you don't need to check whether "informing is turned on", you just call take(), and it will wait for something to appear in the queue.
You could also look into the RxJava project. It is somewhat complex, but it has lots of features you might need.
It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.

Should my custom events fire on GUI EDT or a "home-grown" EDT

I'm working on a project that does some intense math calculations (arrays of matrices, vectors, etc.), so naturally I'm splitting the work into jobs, and submitting them to a CompletionService to perform the work in parallel.
Each of the job objects can fire events to notify applications when the job starts, ends, progresses, and/or fails.
Currently, each of the jobs receive a handle to the entire list of event listeners, and simply iterate through, passing an event object to each one (in the same thread). This doesn't sit well with me, so I'd like to get other peoples' experience with doing this sort of thing with custom events/listeners.
Should I send my events to the GUI thread? Some of the listeners may or may not be GUI-related, and I'd like to not force users of my code to have to manually send their events onto the GUI thread, something like the following:
public class MyFooEventListener implements FooEventListener {
public void notifyJobStarted(FooEvent evt) {
// I want to avoid having users of my library write the following, right?
SwingUtilities.invokeLater(new Runnable(){
// update GUI here.
});
}
}
I wouldn't mind writing my own EventQueue, as this is for a research project in school, and I suppose it would be a good exercise in concurrency. Just trying to figure out what the "proper" way of implementing an event-driven system is, how to properly fire events, etc. Links to articles/tutorials and howtos are also greatly appreciated.
Thanks!
EDIT:
My event model has multiple event types, such as JobStartedEvent, JobEndedEvent, JobProgressEvent, etc. Is this a bad approach? Should I have a single event type, and if so, how do I pass information to the listeners that is not common to all events? Example: I want to pass a double in the range [0-1] for the progress event, but that is not applicable for an event like JobFailureEvent. What's the best approach to handling this?
I could put the extra information in the "source" object itself, but my source objects are the Job objects themselves, and it doesn't sit well with me to "leak" references to the job object, especially while it is running:
FooJob jobObject = (FooJob)event.getSource();
int progressPercent = jobObject.getCurrentProgress() * 100;
progressLabel.setText(progressPercent + "%");
No. Emit your events on whatever thread needs to raise them and leave it up to the users of your subsystem to decide how they wish to handle them. If they wish to message the results to a GUI, fine, if not, they can do whatever they want, eg. queue them to another thread. Just document 'Events are raised on an internal thread and event handlers must not block'.
Anything else puts constraints on users that they may well not want, as you say.
there are many ways to distribute events, each with their own pros and cons. if the consumer is not necessarily the GUI, then you definitely should not tie yourself to the awt EDT. unless you know for sure how the event consumers are going to work i would start simple and go from there. simple being: synchronously notify each consumer. if that ends up delaying the main task, then you should think about asynchronous notification. if the consumer is ultimately the GUI, then the consumer's notification method should be responsible for calling SwingUtilities.invokeLater.
Only threads that directly impact the GUI should be on the EDT. If you have other threads you need synchronized, just use the synchronized keyword (either on the method or on an object)
Spring has event handling and you can define custom events http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#context-functionality-events.

Can I write somethings like a Notification in Java?

In Objective-C I use a Notification to do some tasks, which required some time to process. I can listen to the Notification, until it is ready...
For example:
[[NSNotificationCenter defaultCenter] addObserver:objectB
selector:#selector(objectReceived:)
name:#"objectATasks"
object:nil];
[objectA doALongProcess];
When the objectA is finished the task, the #"objectATasks" will be fired, and the objectB's objectReceived: will be called. Do have have similar things / concept in java? Thank
You can make use of the Observer design pattern in java
Seems that you are using the observer pattern, of course you can implement it also in Java, take a look here .
The closest to that in "stock" Java is a Future, but that doesn't let you add continuations. You may want to use the ListenableFuture interface in Guava with its addListener method. Then you can use MoreExecutors to create a ListeningExecutorService - you submit tasks to that, which gives back a ListenableFuture.
(The point of using this instead of rolling your own implementation of the Observer pattern is that it's already done for you in a way which is specifically designed for this sort of use case, reacting to a task being completed - rather than the various other kinds of observer implementations which may be reacting to just properties changing etc, without considering thread safety. Why design your own API when smart people have already done it for you?)

Use of multiple threads in a Java program and vs need to create Swing objects on EDT

Re: Requirement to create Swing Object on Event-Dispatch Thread.
I am working on an application, the purpose of which is to monitor and display the condition of various remote embedded servers. I'm pretty new to Java, and my understanding of the requirement with respect to the Swing Objects and the EDT is incomplete.
The main GUI is started on the EDT in the usual fashion as follows,
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
The user may then select one or more menu options corresponding to the one or other of the remote machines. The effect of this is to create a new thread each time as follows
new Thread(new VoterStatus(itemNumber)).start();
which invokes VoterStatus's class "run" method which in turn creates a new window with a JFrame. The new thread, an instance of VoterStatus class, then interrogates (TCP etc) the particular remote specified (itemNumber), collecting various bits of information and displaying them in the JFrame.
There may be any number of such threads corresponding to an instance of VoterStatus, all updating their own windows. There is no sharing of data between these various windows/JFrame/tasks.
This seems to work just fine, but is is safe?
Have I violated the rule about creating Swing components on the EDT?
Would use of the SwingWorker class be beneficial?
I would appreciate any comments from Java programmers more experienced in such matters.
Thanks
Steve
From the section in the Swing tutorial titled The Event Dispatch Thread
Some Swing component methods are labelled "thread safe" in the API specification; these can be safely invoked from any thread. All other Swing component methods must be invoked from the event dispatch thread. Programs that ignore this rule may function correctly most of the time, but are subject to unpredictable errors that are difficult to reproduce.
I always invoke my methods on the EDT so I don't waste time chasing gremlins.
Edit:
I just read another posting which states that the comment "thread safe" has been removed from many methods in the JDK7 API. http://forums.oracle.com/forums/thread.jspa?threadID=2167051. This looks like another reason to make sure all methods that affect the GUI are executed on the EDT.
#camickr has the right of it. Incorrectly synchronized programs may appear to work most of the time, but the result is not reliable. Several related approaches are discussed here. SwingWorker is an especially convenient implementation of the Future interface, as process() runs on the event dispatch thread.
You might be safe, but you can be sure by creating your other UI components in the EDT, just like you did for the main application.
However, I would suggest a different approach. Rather than firing off a new Thread which creates the windows and stuff for each new VoterStatus, create the UI components in the EDT in response to ActionEvents from menus or whatever, and do processing of the network stuff only in a different thread. Then get the results and use the EDT to display them. As you've suggested, a SwingWorker is ideal for this - this is exactly the sort of use it was designed for. This represents a cleaner separation for me, separating the UI stuff from the network stuff as much as possible.
I'm not really answering my own question, but I do want to thank those that responded and ask a follow up question or two.
Rogash commented that if I was only creating the GUI on the EDT, I would be ok, but this doesn't seem quite in accordance with a strict interpretation of the rule?
The additional threads are created in the EDT, but they are still separate threads.
Whilst slightly better separation of the GUI and comms may be desirable, I expect this will add considerable complexity to the main GUI code, since it will have to determine which window originated various events and then update the correct window, not to mention the communication between the various threads and the main GUI thread. Perhaps I am overstating this difficulty (I haven't designed or thought about how to code it yet) but it would seem more complicated. Each of the threads/JFrame already has a couple of JToggleButton arrays (30 elements) causing potential events and 10 or so JTextField arrays with the same number of elements requiring updating.
Of course, if my method is unsafe, I'll have to change it, and that's that!
Actually, I wonder if I might be better off leaving things the way they are, and using a mutex or semaphore to make sure only one thread is accessing Swing methods at a time. There is really no long user actions or any other activity takes a long time, just lots of TCP or UDP packets being received that require the screen display to be updated.
Thanks again
Steve
PS I tried to register on this forum, but I think this discussion will stay with my unregistered persona.

Categories

Resources