In Android, each view written in xml layout is parsed and instantiated by LayoutInflater. To get LayoutInflater, one often uses the following three manners:
Actually, the former two APIs in the end invokes the third API
In essence, Layout Inflater Service is not actually a system service like AMS, there are no actual services in the system server, but only wants to be managed in a system-service-alike manner, i.e., managed by Context#getSystemService() (but only registered to SystemServiceRegistry, not ServiceManager, and further not register to servicemanager)
To inflate a layout, one uses LayoutInflate#inflate(). In detail, LayoutInflater#inflate():
firstly tries to load an precompiled view, and return that, if not exists,
then uses XmlResourceParser to parse the XML, reading the classes and attributes, and iterately using reflection to create Views
The Live Layout Update of Android Studio uses poll mechanism. That is, there exists an ART agent daemon installed on the device, loaded to the app's process, and continuously crawling the view hierarchy, and sending tp and caching in the profiler daemon. Android Studio polls the daemon for the new updates (see following architecture)
When does Android Studio establish the connection to the daemon?
What does Android Studio poll?
Implementation
/tools/adt/idea/:layout-inspector
LayoutInspector:50: create a client for accepting events from agent
DefaultInspectorClient:87: create a TransportClient with channel name TransportService.CHANNEL_NAME
DefaultInspectorClient:93: create a TransportEventPoller
DefaultInspectorClient:290: transportPoller registers an event listener
DefaultInspectorClient:284: whenever an event happens, issue a LayoutInspectorCommand.START
LayoutInspector:51: register listeners
when there are COMPONENT_TREE events (this event happens whenever the view hierarchy changed), load the component tree sent (the sent component is a binary stream containing the view hierarchy, and the screen bitmap)
/tools/adt/idea/:android-transport
TransportEventPoller:104: schedule to poll() at a fixed delay
TransportEventPoller:62: each poll, send a Transport.GetEventGroupsRequest, filters out old events, and notifies its listeners if there are new events
/tools/base/:transport
main/transport.cc:78: create the daemon
main/transport.cc:94: start the daemon server
daemon/daemon.cc:205: register an ATTACH_AGENT command
daemon/daemon.cc:216: the server is built and started
daemon/commands/attach_agent.cc:39: attach the agent via ART TI
daemon/daemon.cc:258: actually attach the agent
daemon/daemon.cc:161: run 'cmd activity attach-agent /code_cache/='
is the name of the app
is path under '/data/app/',
is 'libjvmtiagent_x86.so'
is '/data/local/tmp/perfd/agent.config'
native/agent/transport_agent.cc:81: create the agent (i.e., native/agent/agent.cc)
native/agent/commands/layoutinspector_agent_command.cc:33: actual register LAYOUT_INSPECTOR command
native/agent/commands/layoutinspector_agent_command.cc:48: when LAYOUT_INSPECTOR command is issued, method of LayoutInspectorService will be called back
java/.../agent/layoutinspector/LayoutInspectorService:88: when LayoutInspectorCommand::START, detect root change
in DetectRootChange#doInBackground(), when there are root changes, invoke LayoutInspectorService#startLayoutInspector()
crawl view hierarchy (by WindowInspector#getGlobalWindowViews()), compare, then sleep 1s, then crawl, then ...
capture the view properties in LayoutInspectorService#captureAndSendComponentTree(), ComponentTree#{writeTree, loadView}()
capture the bitmap in WindowInspector#getGlobalWindowViews(), LayoutInspectorService#{startLayoutInspector, captureAndSendComponentTree, performViewCapture}()
send the bitmap (image) along with the hierarchy (component tree) in LayoutInspectorService#sendComponentTree(), set the command type as COMPONENT_TREE
java/.../agent/layoutinspector/LayoutInspectorService:88: when LayoutInspectorCommand::GET_PROPERTIES, find the view and gets its properties
use LayoutInspectorService#findViewById()
Why ART TI?
To load the agent in the same process as the app, so that can directly use the app's inner states
Overview
In Android, each view written in xml layout is parsed and instantiated by LayoutInflater. To get LayoutInflater, one often uses the following three manners:
Activity#getLayoutInflater()
LayoutInflater#from(context)
Context#getSystemService(Context.LAYOUT_INFLATER_SERVICE)
Actually, the former two APIs in the end invokes the third API
To inflate a layout, one uses
LayoutInflate#inflate()
. In detail,LayoutInflater#inflate()
:XmlResourceParser
to parse the XML, reading the classes and attributes, and iterately using reflection to createView
sAttributeSet, XmlResourceParser
:warning: TO BE ADDED
References
Live Layout Update (DynamicLayoutInspector)
The Live Layout Update of Android Studio uses poll mechanism. That is, there exists an ART agent daemon installed on the device, loaded to the app's process, and continuously crawling the view hierarchy, and sending tp and caching in the profiler daemon. Android Studio polls the daemon for the new updates (see following architecture)
This involves several questions:
Implementation
/tools/adt/idea/:layout-inspector
/tools/adt/idea/:android-transport
/tools/base/:transport
/tools/base/:profiler
/tools/base/:dynamic-layout-inspector - dynamic layout inspector
Why ART TI?
To load the agent in the same process as the app, so that can directly use the app's inner states