这个方法非常重要,重点做了两个事情:
- 重点1:392行处通过向ViewServer发送”DUMP”命令来获得控件列表,获得谁的控件列表呢?注意”DUMP”命令所带的参数,调用的是刚才哈希值为-1的那个Window的encode方法,而这个方法所做的事情其实就是将-1转换成16进制,请看代码14-8-3。所以这里其实获得的就是屏幕最前面的Activity窗口的所有控件
public String encode() {
return Integer.toHexString(this.mHashCode);
}
代码14-8-3 Window - encode
- 重点2: 在获得所有控件列表之后,394行处就会调用parseViewHierarchy这个方法来解析这个ViewServer返回来的一大串控件列表信息,并且把这些解析出来的控件组建成我们最终的控件树
411 public static ViewNode parseViewHierarchy(BufferedReader in, Window window) {
412 ViewNode currentNode = null;
413 int currentDepth = -1;
414 String line;
415 try {
416 while ((line = in.readLine()) != null) {
417 if ("DONE.".equalsIgnoreCase(line)) {
418 break;
419 }
420 int depth = 0;
421 while (line.charAt(depth) == ' ') {
422 depth++;
423 }
424 while (depth <= currentDepth) {
425 if (currentNode != null) {
426 currentNode = currentNode.parent;
427 }
428 currentDepth--;
429 }
430 currentNode = new ViewNode(window, currentNode, line.substring(depth));
431 currentDepth = depth;
432 }
433 } catch (IOException e) {
434 Log.e(TAG, "Error reading view hierarchy stream: " + e.getMessage());
435 return null;
436 }
437 if (currentNode == null) {
438 return null;
439 }
440 while (currentNode.parent != null) {
441 currentNode = currentNode.parent;
442 }
443 return currentNode;
444 }
代码14-8-4 BridgeDevice - parseViewHierarchy