So in my understanding listener is usually used to trigger some class when some thing happened on particular place. (for example when we click the button we want to do some action).
On the other hand I see some places where callbacks are used to execute/enqueue some code in different place. (retrofit uses this to enqueue API calls)
What is the main difference between these 2?
In short, they are the same.
Really?
Yes. But there are some "theoretical" (and in some cases practical differences).
Concepts
Listener is a word that in Android, it's commonly associated with a View ClickListener or similar. Where there are methods like addxxxListener(...) etc.
A Callback is often heard in the context of "for this particular event" I supply a "callback" and I will be called back when something happens.
In practice, they are often just instances of some interface passed along.
In my limited experience (only about 10 years of Java/Android -now Kotlin as well-), the term is used interchangeably.
I normally think of a callback when I am expecting something to "call me back" when something happens, and a listener as something where I listen to an event but as you can see by reading this... they could be the same. :)
It's often mentioned that one could have multiple listeners, but one callback (but there's nothing enforcing this and I have seen all use cases you can think of where either term is used) "You can add multiple callbacks" is not uncommon, even though if there are "multiple" then it "must be a listener". In fact, if you go as far as Android's View, the method is view.setOnClickListener { }
So it's a Listener, but you can only set ONE. So the above rule about 1 callback, N listeners is already broken since the early days of Android.
In some cases though, the convention is more tied to the method name, rather than the class' name:
setXXXyyy(...) allows you to set "one" and only one yyy listener/callback.
addXXXyyy(...) allows you to add one or more (though not always, so read the documentation) yyy listener/callback.
An add is often (...but not always) accompanied by a removeXXXyyy(...) implying that if you keep/have a reference to a callback/listener you could remove it (and no longer be listening or be called back).
In the case of set, it's often expected that if needed you call set...(null) and pass that null to "remove" the sole listener/callback. (Views do this for you, you don't need to call it, but you can).
Anyway, don't quote me on this, but I'd argue they are the same. This is also more complicated when you involve other languages/frameworks/tools, where there's an even blurrier line.
In many instances, you will see callback used, but the method contains the word "Listener", and vice-verse, so don't get too crazy about it.
If you can, where you can, however, don't use either, just use Coroutines :)
For a concrete example of how both are used as the same thing...
Look at the Android View.setOnClickListener method:
/**
* Register a callback to be invoked when this view is clicked. If this view is not
* clickable, it becomes clickable.
*
* #param l The callback that will run
*
* #see #setClickable(boolean)
*/
public void setOnClickListener(#Nullable OnClickListener l) {
Notice something strange?
The method is called setOnClickListener yet the Javadocs say: "a callback..."
They are the same! Two ways of naming an interface. In general, Listener is also a callback and VICE VERSA!
for a type of event you can have many listeners , but one callback !
A callback is a procedure where you pass as an argument to another procedure. The procedure receiving the parameter can call it, or share it so some other procedures in the system can call it.
A listener watches for an event to be fired. For example, KeyListener waits for KeyEvents, a MessageListener waits for messages to arrive on a queue, and so on.
Related
In my app, i have two buttons that send an event with an ID using an event bus (Otto). Depending on this ID, the app goes to a different level of the navigation between differents fragments. Is possible to avoid that the event bus sends the same event (with different ID) in the same millisecond when the user taps over two different button at the same millisecond?. I attach an image in order to show my Logcat.
Thanks!
EDIT 1:
Using syncronized both onClick method as subscribe method, i continue receiving the events in the same millisecond. Now, the myth about "syncronized" has down for me. O_o
There are posts where they explain how avoid very fast clicks, but here, the clicks are in the same millisecond...rare, but you can see the logs.
I attach new images with the method that i am using. Thanks!
Yes, use synchronized keyword with the method which is generating events (or also with the method which receive events).
For example:
public synchronized void genEvent(){
}
See following related links
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
When to use synchronized in Java
Is there an advantage to use a Synchronized Method instead of a Synchronized Block?
There seem to be (at least) two ways to send Intents in Android:
PendingIntent.send(...)
Activity.startIntentSenderForResult(PendingIntent.getIntentSender(), ...)
Other than the fact that the latter only works starting API level 5 and that the results are passed back in a different way (via PendingIntent.OnFinished vs. Activity.onActivityResult(...)) is there any fundamental difference between the two?
I find the first one a lot more convenient as it can be entirely encapsulated inside a library without requiring the calling activity to override onActivityResult(...) to forward the result (like this: yuck!). Is it ok to still use that approach?
A quick clarification, because I've seen someone complain about this on another question: The methods above are not static methods. I wrote them that way simply for readability.
Seems like these two approaches are very different:
The start...forResult(...) methods start an intent or sub-activity in a way that allows for a result to be returned to the activity that executed the start...forResult(...). The result will be passed back to the activity's onActivityResult(...) method.
All other ways of launching intents or sub-activities (including PendingIntent.send(...)) act in a fire-and-forget-manner and don't allow for any results to be returned. The OnFinished handler is called as soon as the launch is sent, whether or not it takes a while to complete. The data passed into this handler, therefore, does not necessarily have anything to do with what you would otherwise receive via onActivityResult(...). In fact, in my case, the OnFinished handler is always called right away, before the dialog of the sub-activity even shows up, with a resultCode of Activity.RESULT_CANCELED.
What a mess...
I have a 'trick' that I do sometimes in Java/Swing in which I create a swing component that is always invisible and have property change event listener(s) attached to it. When a variable(s) changes value, the code will cause that component to change and fire an event and anything listening will know that those variable(s) have changed.
I want to do this same thing in Android or AndEngine. What would I use instead of the swing component? I'm was thinking of overriding some subclass of org.andengine.entity.Entity, but I don't see any event to fire.
Sounds like you almost hit on it with your Swing idea. There is no event pattern built into andengine, and the reason for this is probably because of the event classes built into the android operating system.
You should have good luck implementing a Listener (Observer Pattern) into your app following the steps in this other Stack Overflow answer:
Custom event listener on Android app
or this simple example in which the broadcaster call a function on a single listener:
Android - event listener
As a footnote, neither example includes code to REMOVE listeners. Be sure your implementation does include that so that you can garbage collect objects you don't need any more.
I have several Activity subclasses in my project, each calling a SOAP based web service, processing and displaying the results. The SOAP serialization, the call handling and the parsing of result into various POJO objects is encapsulated in the MyWebService class. This class executes the actual web service call(s) via an AsyncTask.
For being able to pass back the results to the calling Activity subclass, I figured I enforce that all these activities should implement a WebServiceResultProcessor interface, defining a single function (processWebServiceResults) acting as a callback for the AsyncTask, called from onPostExecute.
I also want to display a ProgressDialog during the web service call. And here comes my question. For being able to display the ProgressDialog (either from MyWebService or it's AsyncTask), I need to pass a reference to the caller Activity's Context. And for being able to execute the callback function from the AsyncTask, I also need to pass the same object reference, but this time as a WebServiceResultProcessor. This seems to me a code smell, passing the same object twice, but can't see any way around that. Instead of interfacing, I could create a new base class, extending the Activity class and enforce inheritance from the extension class, but that would mean I'd exclude ListActivity and the likes from using this MyWebService class.
Is there a better way to do this?
+1, a nice question!
This is not a direct answer on your question. However let me say I think AsyncTask is not a right choice for such stuff. I think so because in this case AsyncTask holds a reference to an Activity (via ProgressDialog instance or the callbacks to be called from onPostExecute()).
Just imagine: in Android the OS may kill the Activity before AsyncTask executes its doInBackground(). This is, of course, some sort of a corner case, but it isn't impossible. Consider a scenario: user gets an incoming call, your activity becomes invisible, the OS needs some more RAM and thus it decides to kill your activity. A memory leak case, at least.
I don't know why Google literally hides the info on how UI should be properly separated from background tasks. Yes, they say "use a Service". But it is not a trivial undertaking. It's a pity Google provides nice guides to almost every development topic, but not on this one. Nevertheless I can suggest to check the "Google I/O 2010 - Android REST client applications" presentation for inspiration. Looks like they gave a key on how such things should be done in Android.
You may have a look into this blog article (part 1 and part 2), which implements a web service with AsyncTaskLoader and the same web service with a Service component. Furthermore it shows the differences between both approaches and there are also interesting comments to the article.
Despite Arhimed's warning, I ended up using AsyncTask, as it still fits my purposes. I just make sure that all Activities calling web services, upon their onDestroy(), send a cancel() to the invoked AsyncTask. The AsyncTask implementation itself gracefully handles the cancel request by checking isCancelled() everywhere where necessary.
As for the original question, I must have had a lapse - the solution is really simple. I pass the Activity subclass instance as an Object to the AsyncTask, and cast it to either Context or to WebServiceResultProcessor, as necessary. Fragments showing how it works:
if (callerActivity instanceof Context) {
ProgressDialog dialog = new ProgressDialog((Context)callerActivity);
}
...
if (callerActivity instanceof WebServiceResultProcessor) {
((WebServiceResultProcessor)callerActivity).processWebServiceResults(soapObject);
}
I've a custom class whose parent is SurfaceView. I have the class working correctly, drawing to the screen from its own thread etc. However I want to understand how the methods in the question title should be correctly handled.
For example, if my app is running (on a mobile phone) and a call is received, which method is called? Another example is if I implement a dialog box to be displayed if the user 'long-presses' on my custom SurfaceView, what method is called then? I assume the canvas is 'safe' to write to provided surfaceDestroyed() has not been called.
Basically I want to understand how I should handle eventualities as I've described (and possibly more?) and for what events each method is called.
on...-methods are called when something happened.
You probably don't have to implement them because the super class does the correct things in most cases.
If you put log in the methods in question you can see what happens / when they are called. You can also read the API doc and have a look at the source code to see what is done there.