googios uiautomationn 支持ID属性吗

Configuring IS-IS Multi Area and Summary -IT行业第一站
实验步骤及要求: 1、配置各台路由器的IP地址" />
Configuring IS-IS Multi Area and Summary Route
Configuring IS-IS Multi Area and Summary Route
标题:Configuring IS-IS Multi Area and Summary Route
实验目的:
1、掌握基本的IS-IS路由协议配置。
2、理解L1/L2类型路由。
3、掌握IS-IS区域汇总的配置。
实验拓扑图:
500)this.width=500;" border=0>
实验步骤及要求:
1、配置各台路由器的IP地址,并且使用Ping命令确认各路由器的直连口的互通性。
2、各台路由器的IS-IS配置如下。
R1(config)#interface&Loopback0
R1(config-if)#ip&address&172.16.1.1&255.255.255.0
R1(config-if)#ip&router&isis&cisco
R1(config-if)#isis&circuit-type&level-1
R1(config-if)#exit
R1(config)#
R1(config)#interface&Loopback1
R1(config-if)#ip&address&172.16.2.1&255.255.255.0
R1(config-if)#ip&router&isis&cisco
R1(config-if)#isis&circuit-type&level-1
R1(config-if)#exit
R1(config)#
R1(config)#interface&Serial1/1
R1(config-if)#ip&address&172.16.255.1&255.255.255.252
R1(config-if)#ip&router&isis&cisco
R1(config-if)#isis&circuit-type&level-2-only
R1(config-if)#exit
R1(config)#
R1(config)#router&isis&cisco
R1(config-if)#net&49.0001.ca00.0bbc.0000.00
R1(config-if)#exit
R1(config)#
R2(config)#interface&Serial1/0
R2(config-if)#ip&address&172.16.255.2&255.255.255.252
R2(config-if)#ip&router&isis&cisco
R2(config-if)#isis&circuit-type&level-2-only
R2(config-if)#exit
R2(config)#
R2(config)#interface&Serial1/1
R2(config-if)#ip&address&172.16.255.5&255.255.255.252
R2(config-if)#ip&router&isis&cisco
R2(config-if)#exit
R2(config)#
R2(config)#router&isis&cisco
R2(config-if)#net&49.0002.ca01.0bbc.0000.00
R2(config-if)#exit
R2(config)#
R3(config)#interface&Serial1/0
R3(config-if)#ip&address&172.16.255.6&255.255.255.252
R3(config-if)#ip&router&isis&cisco
R3(config-if)#exit
R3(config)#
R3(config-if)#interface&Serial1/1
R3(config-if)#ip&address&172.16.255.9&255.255.255.252
R3(config-if)#ip&router&isis&cisco
R3(config-if)#isis&circuit-type&level-2-only
R3(config-if)#exit
R3(config)#
R3(config-if)#router&isis&cisco
R3(config-if)#net&49.0002.ca02.0bbc.0000.00
R3(config-if)#exit
R3(config)#
R4(config)#interface&Serial1/0
R4(config-if)#ip&address&172.16.255.10&255.255.255.252
R4(config-if)#ip&router&isis&cisco
R4(config-if)#isis&circuit-type&level-2-only
R4(config-if)#exit
R4(config)#
R4(config-if)#interface&Serial1/1
R4(config-if)#ip&address&172.16.255.13&255.255.255.252
R4(config-if)#ip&router&isis&cisco
R4(config-if)#isis&circuit-type&level-1
R4(config-if)#exit
R4(config)#
R4(config-if)#router&isis&cisco
R4(config-if)#net&49.0003.ca03.0bbc.0000.00
R4(config)#exit
R4(config)#
R5(config)#interface&Loopback0
R5(config-if)#ip&address&172.16.128.1&255.255.255.0
R5(config-if)#ip&router&isis&cisco
R5(config-if)#isis&circuit-type&level-1
R5(config-if)#exit
R5(config)#
R5(config-if)#interface&Loopback1
R5(config-if)#ip&address&172.16.129.1&255.255.255.0
R5(config-if)#ip&router&isis&cisco
R5(config-if)#exit
R5(config)#
R5(config-if)#interface&Serial1/0
R5(config-if)#ip&address&172.16.255.14&255.255.255.252
R5(config-if)#ip&router&isis&cisco
R5(config-if)#exit
R5(config)#
R5(config-if)#router&isis&cisco
R5(config-if)#net&49.0003.ca04.0bbc.0000.00
R5(config-if)#is-type&level-1
R5(config-if)#exit
R5(config)#
4、查看R2、R3、R4的邻居表,观察其多区域环境下的邻居关系:
R2#show&isis&neighbors&
System&Id&&&&&&Type&Interface&IP&Address&&&&&&State&Holdtime&Circuit&Id
R3&&&&&&&&&&&&&L1L2&Se1/1&&&&&172.16.255.6&&&&UP&&&&29&&&&&&&01
R1&&&&&&&&&&&&&L2&&&Se1/0&&&&&172.16.255.1&&&&UP&&&&23&&&&&&&00
R3#show&isis&neighbors&
System&Id&&&&&&Type&Interface&IP&Address&&&&&&State&Holdtime&Circuit&Id
R2&&&&&&&&&&&&&L1L2&Se1/0&&&&&172.16.255.5&&&&UP&&&&25&&&&&&&01
R4&&&&&&&&&&&&&L2&&&Se1/1&&&&&172.16.255.10&&&UP&&&&27&&&&&&&00
R4#show&isis&neighbors&
System&Id&&&&&&Type&Interface&IP&Address&&&&&&State&Holdtime&Circuit&Id
R3&&&&&&&&&&&&&L2&&&Se1/0&&&&&172.16.255.9&&&&UP&&&&23&&&&&&&00
R5&&&&&&&&&&&&&L1&&&Se1/1&&&&&172.16.255.14&&&UP&&&&22&&&&&&&00
5、查看R1与R5的路由表,观察其区别:
R1#show&ip&route&
Gateway&of&last&resort&is&not&set
&&&&&172.16.0.0/16&is&variably&subnetted,&8&subnets,&2&masks
i&L2&&&&172.16.128.0/24&[115/50]&via&172.16.255.2,&Serial1/1
i&L2&&&&172.16.129.0/24&[115/50]&via&172.16.255.2,&Serial1/1
C&&&&&&&172.16.255.0/30&is&directly&connected,&Serial1/1
i&L2&&&&172.16.255.4/30&[115/20]&via&172.16.255.2,&Serial1/1
i&L2&&&&172.16.255.8/30&[115/30]&via&172.16.255.2,&Serial1/1
i&L2&&&&172.16.255.12/30&[115/40]&via&172.16.255.2,&Serial1/1
C&&&&&&&172.16.1.0/24&is&directly&connected,&Loopback0
C&&&&&&&172.16.2.0/24&is&directly&connected,&Loopback1
R1#show&isis&database&
IS-IS&Level-1&Link&State&Database:
LSPID&&&&&&&&&&&&&&&&&LSP&Seq&Num&&LSP&Checksum&&LSP&Holdtime&&&&&&ATT/P/OL
R1.00-00&&&&&&&&&&&&*&0x0000000B&&&0xD33B&&&&&&&&679&&&&&&&&&&&&&&&1/0/0
IS-IS&Level-2&Link&State&Database:
LSPID&&&&&&&&&&&&&&&&&LSP&Seq&Num&&LSP&Checksum&&LSP&Holdtime&&&&&&ATT/P/OL
R1.00-00&&&&&&&&&&&&*&0x0000000E&&&0xCC4D&&&&&&&&736&&&&&&&&&&&&&&&0/0/0
R2.00-00&&&&&&&&&&&&&&0x&&&0xA297&&&&&&&&427&&&&&&&&&&&&&&&0/0/0
R3.00-00&&&&&&&&&&&&&&0x0000000F&&&0x65C8&&&&&&&&1097&&&&&&&&&&&&&&0/0/0
R4.00-00&&&&&&&&&&&&&&0x&&&0x4B41&&&&&&&&818&&&&&&&&&&&&&&&0/0/0
R5#show&ip&route&
Gateway&of&last&resort&is&172.16.255.13&to&network&0.0.0.0
&&&&&172.16.0.0/16&is&variably&subnetted,&3&subnets,&2&masks
C&&&&&&&172.16.128.0/24&is&directly&connected,&Loopback0
C&&&&&&&172.16.129.0/24&is&directly&connected,&Loopback1
C&&&&&&&172.16.255.12/30&is&directly&connected,&Serial1/0
i*L1&0.0.0.0/0&[115/10]&via&172.16.255.13,&Serial1/0
R5#show&isis&database&
IS-IS&Level-1&Link&State&Database:
LSPID&&&&&&&&&&&&&&&&&LSP&Seq&Num&&LSP&Checksum&&LSP&Holdtime&&&&&&ATT/P/OL
R4.00-00&&&&&&&&&&&&&&0x0000000C&&&0x7BA1&&&&&&&&770&&&&&&&&&&&&&&&1/0/0
R5.00-00&&&&&&&&&&&&*&0x0000000D&&&0xF411&&&&&&&&649&&&&&&&&&&&&&&&0/0/0
6、使用ping命令确认路由:
R1#ping&172.16.129.1
Type&escape&sequence&to&abort.
Sending&5,&100-byte&ICMP&Echos&to&172.16.129.1,&timeout&is&2&seconds:
Success&rate&is&100&percent&(5/5),&round-trip&min/avg/max&=&220/240/264&ms
7、为了能够更有效的减小路由表的大小,还可以配置IS-IS的汇总。首先查看R4的路由表:
R4#show&ip&route&
Gateway&of&last&resort&is&not&set
&&&&&172.16.0.0/16&is&variably&subnetted,&8&subnets,&2&masks
i&L1&&&&172.16.128.0/24&[115/20]&via&172.16.255.14,&Serial1/1
i&L1&&&&172.16.129.0/24&[115/20]&via&172.16.255.14,&Serial1/1
i&L2&&&&172.16.255.0/30&[115/30]&via&172.16.255.9,&Serial1/0
i&L2&&&&172.16.255.4/30&[115/20]&via&172.16.255.9,&Serial1/0
C&&&&&&&172.16.255.8/30&is&directly&connected,&Serial1/0
C&&&&&&&172.16.255.12/30&is&directly&connected,&Serial1/1
i&L2&&&&172.16.1.0/24&[115/40]&via&172.16.255.9,&Serial1/0
i&L2&&&&172.16.2.0/24&[115/40]&via&172.16.255.9,&Serial1/0
8、在R1上配置地址总结:
R1(config)#router&isis&cisco
R1(config-router)#summary-address&172.16.0.0&255.255.128.0
R1(config-router)#exit
R1(config)#exit
9、再次查看R4的路由表:
R4#show&ip&route&
Gateway&of&last&resort&is&not&set
&&&&&172.16.0.0/16&is&variably&subnetted,&7&subnets,&3&masks
i&L1&&&&172.16.128.0/24&[115/20]&via&172.16.255.14,&Serial1/1
i&L1&&&&172.16.129.0/24&[115/20]&via&172.16.255.14,&Serial1/1
i&L2&&&&172.16.255.0/30&[115/30]&via&172.16.255.9,&Serial1/0
i&L2&&&&172.16.255.4/30&[115/20]&via&172.16.255.9,&Serial1/0
C&&&&&&&172.16.255.8/30&is&directly&connected,&Serial1/0
C&&&&&&&172.16.255.12/30&is&directly&connected,&Serial1/1
i&L2&&&&172.16.0.0/17&[115/40]&via&172.16.255.9,&Serial1/0
10、确认汇总路由有效性:
R4#ping&172.16.1.1
Type&escape&sequence&to&abort.
Sending&5,&100-byte&ICMP&Echos&to&172.16.1.1,&timeout&is&2&seconds:
Success&rate&is&100&percent&(5/5),&round-trip&min/avg/max&=&192/225/240&ms
11、实验完成.&
延伸阅读:
热门搜索:3442人阅读
在使用MonkeyRunner的时候我们经常会用到Chimchat下面的HierarchyViewer模块来获取目标控件的一些信息来辅助我们测试,但在MonkeyRunner的官网上是没有看到相应的API的描述的,上面只有以下三个类的API引用信息()
MonkeyDeviceMonkeyImageMonkeyRunner
所以在这里尝试整理下HierarchyViewer提供的API的用法并根据实践作出相应的建议,首先请看该类提供的所有可用的公共方法,内容并不多:
从图中可以看出HierarchyViewer类中提供的方法主要是用来定位控件相关的,包括根据ID取得控件,根据控件取得控件在屏幕的位置等。但还有一些其他方法,我们会顺带一并描述,毕竟内容并不多。
本文我们依然跟上几篇文章一样以SDK自带的NotePad为实验目标,看怎么定位到NotesList下面的Menu Options中的Add note这个Menu Entry。
以下是通过HierarchyViewer这个工具获得的目标设备界面的截图:
2.findViewById(String id)
targetDevice = MonkeyRunner.waitForConnection()
'''
public ViewNode findViewById(String id)
* @param id id for the view.
* @return view with the specified ID, or {@code null} if no view found.
'''
viewer = targetDevice.getHierarchyViewer()
button = viewer.findViewById('id/title')
text = viewer.getText(button)
print text.encode('utf-8')
2.2 分析和建议
此API的目的就是通过控件的ID来获得代表用户控件的一个ViewNode对象。因为这个是第一个示例,所以这里有几点需要说明
一旦MonkeyRunner连接上设备,会立刻获得一个MonkeyDevice的对象代表了目标测试设备,我们就是通过这个设备对象来控制设备的注意这里需要填写的id的格式和UIAutomatorViewer获得ResourceId是不一样的,请看下图UIAutomatorViewer截图中ResourceId前面多出了&android:&字串:这个方法返回的一个ViewNode的对象,代表目标控件,拥有大量控件相关的属性,由于篇幅问题这里不详述,往后应该会另外撰文描述它的使用。在本文里知道它代表了目标控件就行了最后打印的时候需要转换成UTF-8编码的原因跟Jython默认的编码格式有关系,具体描述和Workaround请查看:
3. findViewById(String id, ViewNode rootNode)
'''
public ViewNode findViewById(String id, ViewNode rootNode)
* Find a view by ID, starting from the given root node
* @param id ID of the view you're looking for
* @param rootNode the ViewNode at which to begin the traversal
* @return view with the specified ID, or {@code null} if no view found.
'''
iconMenuView = viewer.findViewById('id/icon_menu')
button = viewer.findViewById('id/title',iconMenuView)
print &Button Text:&,text.encode('utf-8')
这个方法是上面方法的一个重载,除了需要指定ID之外,还需要指定一个rootNode,该rootNode指的就是已知控件的父控件,父到什么层级就没有限制了。为什么需要这个方法了,我们可以想象下这种情况:同一界面上存在两个控件拥有相同的ID,但是他们某一个层级父控件开始发生分叉。那么我们就可以把rootNode指定为该父控件(不包括)到目标控件(不包含)路径中的其中一个父控件来精确定位我们需要的目标控件了。
如我们的示例就是明确指出我们需要的是在父控件“id/icon_menu&(请看背景的hierarchyviewer截图)下面的那个”id/title&控件。
4 getAbsolutePositionOfView(ViewNode node)
'''
public static Point getAbsoluteCenterOfView(ViewNode node)
* Gets the absolute x/y center of the specified view node.
* @param node view node to find position of.
* @return absolute x/y center of the specified view node.
'''
point = viewer.getAbsoluteCenterOfView(button)
print &Button Absolute Center Position:&,point
4.2 分析和建议
这个API的目的是想定位一个已知ViewNode控件的左上角在屏幕上的绝对坐标。对于我们正常的APP里面的控件,本人实践过是没有问题的。但是有一种情况要特别注意:这个对Menu Options下面的控件是无效的!
以上示例最后一段代码的输出是(3,18),其实这里不用想都知道这个不可能是相对屏幕左上角坐标(0,0)的绝对坐标值了,就偏移这一点点像素,你真的当我的实验机器HTC Incredible S是可以植入脑袋的神器啊。
那么这个数据是如何获得的呢?其实按照我的理解(真的只是我自己的理解,不对的话就指正吧,但请描述详细点以供我参考),这个函数的定义应该是“获得从最上层的DecorView(具体DectorView的描述请查看我以前转载的一篇文章《》)左上角坐标到目标控件的的偏移坐标”,只是这个最上层的DecorView的坐标一般都是从(0,0)开始而已。如下图我认为最上面的那个FrameLayout就代表了DecorView,或者说整个窗体
那么在假设我的观点是对的情况下,这个就很好解析了,请看Menu Option的最上层FrameLayout的绝对坐标是(0,683)
而Add note的绝对坐标是(3,701)
两者一相减就是和我们的输出结果绝对吻合的(3,18)了。
5. getAbsoluteCenterOfView(ViewNode node)
'''
public static Point getAbsoluteCenterOfView(ViewNode node)
* Gets the absolute x/y center of the specified view node.
* @param node view node to find position of.
* @return absolute x/y center of the specified view node.
'''
point = viewer.getAbsoluteCenterOfView(button)
print &Button Absolute Center Position:&,point
5.2 分析和建议
这个方法的目的是获得目标ViewNode控件的中间点的绝对坐标值,但是对Menu Options下面的控件同样不适用,具体请查看第3章节。
以下两个方法都不是用来定位控件的,一并记录下来以供参考。
6. getFocusedWindowName()
'''
public String getFocusedWindowName()
* Gets the window that currently receives the focus.
* @return name of the window that currently receives the focus.
'''
window = viewer.getFocusedWindowName()
print &Window Name:&,window.encode('utf-8')
其实就是获得当前打开的窗口的packageName/activityName,输出与HierarchyViewer工具检测到的信息一致,所以猜想其用到同样的方法。
HierarchyViewer监控信息:
7. visible(ViewNode node)
'''
public boolean visible(ViewNode node)
* Gets the visibility of a given element.
* @param selector selector for the view.
* @return True if the element is visible.
'''
isVisible = viewer.visible(button)
print &is visible:&,isVisible就是查看下控件是否可见,没什么好解析的了。
8. 测试代码
from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice
from com.android.monkeyrunner.easy import EasyMonkeyDevice,By
from com.android.chimpchat.hierarchyviewer import HierarchyViewer
from com.android.hierarchyviewerlib.models import ViewNode, Window
from java.awt import Point
#from com.android.hierarchyviewerlib.device import
#Connect to the target targetDevice
targetDevice = MonkeyRunner.waitForConnection()
easy_device = EasyMonkeyDevice(targetDevice)
#touch a button by id would need this
targetDevice.startActivity(component=&com.example.android.notepad/com.example.android.notepad.NotesList&)
#time.sleep(2000)
#invoke the menu options
MonkeyRunner.sleep(6)
targetDevice.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP);
'''
public ViewNode findViewById(String id)
* @param id id for the view.
* @return view with the specified ID, or {@code null} if no view found.
'''
viewer = targetDevice.getHierarchyViewer()
button = viewer.findViewById('id/title')
text = viewer.getText(button)
print text.encode('utf-8')
'''
public ViewNode findViewById(String id, ViewNode rootNode)
* Find a view by ID, starting from the given root node
* @param id ID of the view you're looking for
* @param rootNode the ViewNode at which to begin the traversal
* @return view with the specified ID, or {@code null} if no view found.
'''
iconMenuView = viewer.findViewById('id/icon_menu')
button = viewer.findViewById('id/title',iconMenuView)
print &Button Text:&,text.encode('utf-8')
'''
public String getFocusedWindowName()
* Gets the window that currently receives the focus.
* @return name of the window that currently receives the focus.
'''
window = viewer.getFocusedWindowName()
print &Window Name:&,window.encode('utf-8')
'''
public static Point getAbsoluteCenterOfView(ViewNode node)
* Gets the absolute x/y center of the specified view node.
* @param node view node to find position of.
* @return absolute x/y center of the specified view node.
'''
point = viewer.getAbsoluteCenterOfView(button)
print &Button Absolute Center Position:&,point
'''
public static Point getAbsolutePositionOfView(ViewNode node)
* Gets the absolute x/y position of the view node.
* @param node view node to find position of.
* @return point specifying the x/y position of the node.
'''
point = viewer.getAbsolutePositionOfView(button)
print &Button Absolute Position:&, point
'''
public boolean visible(ViewNode node)
* Gets the visibility of a given element.
* @param selector selector for the view.
* @return True if the element is visible.
'''
isVisible = viewer.visible(button)
print &is visible:&,isVisible
9.附上HierarchyViewer类的源码方便参照
* Copyright (C) 2011 The Android Open Source Project
* Licensed under the Apache License, Version 2.0 (the &License&);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an &AS IS& BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
package com.android.chimpchat.
import com.android.ddmlib.ID
import com.android.ddmlib.L
import com.android.hierarchyviewerlib.device.DeviceB
import com.android.hierarchyviewerlib.device.ViewServerD
import com.android.hierarchyviewerlib.models.ViewN
import com.android.hierarchyviewerlib.models.W
import org.eclipse.swt.graphics.P
* Class for querying the view hierarchy of the device.
public class HierarchyViewer {
public static final String TAG = &hierarchyviewer&;
private IDevice mD
* Constructs the hierarchy viewer for the specified device.
* @param device The Android device to connect to.
public HierarchyViewer(IDevice device) {
this.mDevice =
setupViewServer();
private void setupViewServer() {
DeviceBridge.setupDeviceForward(mDevice);
if (!DeviceBridge.isViewServerRunning(mDevice)) {
if (!DeviceBridge.startViewServer(mDevice)) {
// TODO: Get rid of this delay.
Thread.sleep(2000);
} catch (InterruptedException e) {
if (!DeviceBridge.startViewServer(mDevice)) {
Log.e(TAG, &Unable to debug device & + mDevice);
throw new RuntimeException(&Could not connect to the view server&);
DeviceBridge.loadViewServerInfo(mDevice);
* Find a view by id.
* @param id id for the view.
* @return view with the specified ID, or {@code null} if no view found.
public ViewNode findViewById(String id) {
ViewNode rootNode = DeviceBridge.loadWindowData(
new Window(new ViewServerDevice(mDevice), &&, 0xffffffff));
if (rootNode == null) {
throw new RuntimeException(&Could not dump view&);
return findViewById(id, rootNode);
* Find a view by ID, starting from the given root node
* @param id ID of the view you're looking for
* @param rootNode the ViewNode at which to begin the traversal
* @return view with the specified ID, or {@code null} if no view found.
public ViewNode findViewById(String id, ViewNode rootNode) {
if (rootNode.id.equals(id)) {
return rootN
for (ViewNode child : rootNode.children) {
ViewNode found = findViewById(id,child);
if (found != null) {
* Gets the window that currently receives the focus.
* @return name of the window that currently receives the focus.
public String getFocusedWindowName() {
int id = DeviceBridge.getFocusedWindow(mDevice);
Window[] windows = DeviceBridge.loadWindows(new ViewServerDevice(mDevice), mDevice);
for (Window w : windows) {
if (w.getHashCode() == id)
return w.getTitle();
* Gets the absolute x/y position of the view node.
* @param node view node to find position of.
* @return point specifying the x/y position of the node.
public static Point getAbsolutePositionOfView(ViewNode node) {
int x = node.
int y = node.
ViewNode p = node.
while (p != null) {
x += p.left - p.scrollX;
y += p.top - p.scrollY;
return new Point(x, y);
* Gets the absolute x/y center of the specified view node.
* @param node view node to find position of.
* @return absolute x/y center of the specified view node.
public static Point getAbsoluteCenterOfView(ViewNode node) {
Point point = getAbsolutePositionOfView(node);
return new Point(
point.x + (node.width / 2), point.y + (node.height / 2));
* Gets the visibility of a given element.
* @param selector selector for the view.
* @return True if the element is visible.
public boolean visible(ViewNode node) {
boolean ret = (node != null)
&& node.namedProperties.containsKey(&getVisibility()&)
&& &VISIBLE&.equalsIgnoreCase(
node.namedProperties.get(&getVisibility()&).value);
* Gets the text of a given element.
* @param selector selector for the view.
* @return the text of the given element.
public String getText(ViewNode node) {
if (node == null) {
throw new RuntimeException(&Node not found&);
ViewNode.Property textProperty = node.namedProperties.get(&text:mText&);
if (textProperty == null) {
// give it another chance, ICS ViewServer returns mText
textProperty = node.namedProperties.get(&mText&);
if (textProperty == null) {
throw new RuntimeException(&No text property on node&);
return textProperty.
10. 参考阅读
以下是之前不同框架的控件定位的实践,一并列出来方便直接跳转参考:
天地会珠海分舵
服务号:TechGoGoGo
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:214987次
积分:4789
积分:4789
排名:第2666名
原创:120篇
转载:27篇
译文:144篇
评论:100条
文章:17篇
阅读:7282
文章:20篇
阅读:9602
文章:134篇
阅读:61296
阅读:14786
文章:10篇
阅读:23231
文章:10篇
阅读:19768
文章:21篇
阅读:32370
文章:35篇
阅读:70218
(10)(28)(8)(15)(73)(41)(18)(2)(8)(42)(36)(6)(4)

我要回帖

更多关于 googleagent 的文章

 

随机推荐