Android AccessibilityNodeInfo refresh () and recycle ()
I have read the Android documentation at https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html
I don't understand the description given in the document about the recycle () and refresh () methods.
1.recycle () - returns an instance back for reuse.
- The instance goes back to where?
- In what scenario will this instance be reused?
- AccessibilityNodeInfo can contain a child node, do I need to call recycle () when my code navigates to each node, or just call the recycle method on the root node?
2.refresh () - refreshes this information with the last state of the view it represents
- I thought that when the onAccessibilityEvent () method was called, the AccessibilityEvent should contain the latest state?
- AccessibilityNodeInfo can contain a child node, do I need to call refresh () when my code navigates to each node, or just call the refresh method on the root node?
source to share
The Android Accessibility API uses a node pool AccessibilityNodeInfo
. This way, iterating over large trees will not create many objects that the garbage collector will slow down. In other words, when you recycle the () node, you can later (for example, in the next case or when iterating over the same tree) get the same node object again, but filled with completely different details. Therefore, it is important that you do not refer to nodes that you have reworked (for example, try comparing them to other nodes).
When you get child nodes, you need to recycle every child node. When you don't get them, you don't need to recycle them. You can recycle children before recycle parents, or vice versa, depending on how long it takes you to access the objects.
When you get a node, it contains the latest state. But when you perform an action on it (like click or scroll), the state of a node or other nodes may change. If you want to see these changes in real time (and not only when the next event is received), you need to update the () node (or you can update () the root and try to get a new copy of the node from the root)
When you just got the child nodes, you don't need to update them (they are already fresh). You only need to update the nodes you received earlier (before doing some interaction with them or with other nodes).
source to share
recycle ()
In my (relatively short) use of the accessibility service, you probably don't expect a call recycle()
,or at least not on nodes that you did not explicitly request (for example, using one of the functions mentioned below); I got some pretty random crashes due to the standby cache (in the SDK) clearing out the nodes it itself was holding (!)and I looked at the source code and it seems that all called nodes are added to the fallback cache which is cleared later. There are several ways to safely check if a node has already been redesigned and the SDK code is definitely not.
Holding on to the nodes, I found that they end up being reworked by some SDK code too, so I noticed that developers might not expect them to do this themselves.
update ()
When you receive a knot, it is accurate. If you take any action that gives you another node ( getChild(i)
, findAccessibilityNodeInfosByViewId(viewId)
etc.), the SDK calls the function to get the latest information - so it will be accurate at the time.
It seems relatively safe to hold the nodes while you validate them; However, most functions that do not pay attention to fields will throw an exception if the node has already been redesigned somewhere. So: I would recommend that you create a handy function isValid()
to check this on all nodes. Just make sure it's non-zero (some events will give you a null source!) And that the attribute is className
non-zero (it's always safe to check and null when not in use or being recycled).
source to share