I am keen to know how Android's event handling and dispatching work. Code walk-through is an option, of course. But, if there's any document one can refer me to, that'd be great.
As a concrete example, consider a click event on a button. How does that click propagate within the framework? In case of multiple event occurring one after another, is there some sort of event queue, and a dispatcher calling methods on the events in the queue? What goes on under the hood? If not any document, if one can point me to the relevant part of the code I should look at, that'd be great.
According to my knowledge the parent is the first asked, if he can handle the event, otherwise he asks his childs who can handle this event ?
https://developer.android.com/training/gestures/viewgroup
Related
Some actions from the user may trigger multiple events and handlers, like the well known LongClick ~> Click.
I am looking for some kind of a hierarchy graph that summarizes this potential trigger-order relation for Android Events, but no success so far.
Any pointer on this please ?
We have started to look into the Building Accessibility Service for Android at https://developer.android.com/guide/topics/ui/accessibility/services.html. Based on this documentation, we can perform custom gestures on behalf of user as mentioned under section "Taking actions for users" at https://developer.android.com/guide/topics/ui/accessibility/services.html#act-for-users.
We have following questions based on this documentation.
1) As we understand, there are gestures that user would perform and our code would listen to. Let's call these Listening Gestures. Then there are gestures that could be performed by our code for user. Let's call these Performing Gestures. Question is where do Performing Gestures impact - over touch-and-explore layer or underneath the touch-and-explore layer? For additional information, touch-and-explore is feature of Android Operating System that can be requested by Accessibility Services.
2) Does the Performing Gesture trigger any AccessibilityEvent which is notified to Accessibility Service? If yes, there's possible recursion if both Listening Gesture and Performing Gesture happen to be same. That is Listening Gesture could be swipe right which triggers some event. Performing Gesture is also let's say a swipe right. Now, this will also in turn trigger same event handler.
3) How do we determine that Performing Gesture executed successfully? The whole thing holds significance if Performing Gesture happens underneath the touch-and-explore layer.
Any help would be greatly appreciated.
1) No, performing gestures on behalf of users utilizing Accessibility service capabilities DOES NOT end up being caught as a "listening" gesture. The AccessibilityService actually sends the gesture through to the API that calculates screen touches in the exact same way that the screen does, circumventing the screen completely. So, these events are invisible to the assisstive technology. Though, if you hang on to a reference, you could of course call the callbacks from AccessibilityService for these gestures yourself. So, any gesture you perform will not trigger a touch to explore gesture. In fact, you could trigger performing a gesture as a result of a touch to explore gesture.
2) This, to me is actually the same question as question 1. No, it does not, because of all of the same reasons in question 1.
3) There are two answers to this. The first is 'dispatchGesture' returns a boolean. This boolean is true when the operating system runs into no technical issues dispatching your gesture. Potential issues for example would be: Your attempting to interact off screen. This would be stupid of you! LOL. If a "true" is returned from this method, your gesture was generally accpetable and was performed. At this point, we can be as sure that a gesture was performed as a user actually performing the gesture themselves. It's the exact same logic in the Operating System... check out the AOSP for yourself if you don't believe me :)
3B) The only way to be sure things are working is to watch your gesture take actions on the screen.
I was troubleshooting a view-related issue: a click listener that is not fired when it's supposed to. After a long session of trial-and-error, I found out that a parent view was disabled, thus discarding all events to its children.
Is there a way, in Android, to find exactly what happens to a touch or click event when it is injected to the app? Like how was it dispatched, which views were traversed by it, who ignored it (and why), who discarded it (and why) and finally who consumed it.
Ideally it would be some kind of low-level dump on Logcat emitted for every click in the app.
As you can see in the similar post at the issue tracker Dianne Hackborn writes:
There currently isn't a way to do this.
Meaning, there is no such an API in the framework.
But you can have a custom root ViewGroup and listen for each and every touch event (via onInterceptTouchEvent()) and dump the MotionEvent.
I believe that's the only possible way so far.
I'm using the GreenRobot EventBus lib on Android.
Could someone tell me, what's best practice for calling the removeStickyEvent(...)? Up-Action, back button pressed, ...?
Thank you guys.
To answer your question about the Event object staying in memory: only the last sticky event posted stays in memory for each given type.
Take a look at the source here.
Basically to summarize: Eventbus keeps a map of stickyEvents with the key being class type and the value being the field. So when a new sticky event is posted with EventBus.postSticky(event) the event posted overwrites the old event. So I think you are safe from building up many sticky events.
I was worried about that also. I wish it was explained better in the docs but at least its open source so we can look inside and see whats happening.
I guess to answer your question more completely. When should you remove a sticky event? When you don't want calls to get the sticky event to not return anything. When exactly that is is an application specific requirement. Good luck.
Is it good practice to use Otto event bus bi-directionally?
I mean, send events from controller to view, and view to controller?
Or is it just meant to publish results meaning its purpose is only events from controller to view?
Thanks
Good question. Here is my thoughts on this. I use Otto for a while and use it bi-directionally. From my experience there is nothing against doing this. I have just defined couple of rules helping me keep everything under control.
One-to-many pattern must be confirmed. I mean here, that one producer should normally notify multiple subscribers. Of course, at different point in time there can be zero or more subscribers. But if you have a case, where by-design maximum number of subscribers is just one, then you trying to dispatch rather a "command", than an "event". For such cases I would use a direct call instead of posting a event.
Another thing to avoid should be a situation, when one event triggers another event, which, in turn, triggers first event again. You can run in infinite event chain here. This might happen when same class has the both subscriber and producer methods. If I have such classes, I try to keep those methods as independent as possible.
And of course I always use Android components' lifecycle to register and unregister publishers and subscribers dynamically. I start with onResume() and onPause() methods and, if needed, I'm going up to onStart() or even onCreate().