var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-333696-1']); _gaq.push(['_trackPageview']); _gaq.push(['_trackPageLoadTime']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();
  • 2011年09月16日

    单台PC通过adb连接多个设备

    分类:

    adb只能支持16台设备并发运行,adb 服务器(adb fork-server server)扫描设备端口号范围为5554~5585,其中偶数端口用作控制台连接,基数号端口用作adb连接,相邻的两个基偶数端口组合起来控制一台设备。

     

    本地虚拟机adb的连接上限定义在宏ADB_LOCAL_TRANSPORT_MAXtranspoft_local.c):

    #define ADB_LOCAL_TRANSPORT_MAX 16

    其连接端口为宏DEFAULT_ADB_LOCAL_TRANSPORT_PORTadb.h):

    #define DEFAULT_ADB_PORT 5037

    #define DEFAULT_ADB_LOCAL_TRANSPORT_PORT 5555

    transpoft_local.c中静态函数client_socket_threadfor循环创建ADB_LOCAL_TRANSPORT_MAX个连接(local_connect,它调用local_connect_arbitrary_ports,传入参数为相邻的端口号从(DEFAULT_ADB_LOCAL_TRANSPORT_PORT-1)开始;在函数local_connect_arbitrary_ports中调用socket_network_clientsocket_network_client.c)以判断是否能连接上给定IP的端口,如果能够连上则用register_socket_transport注册),端口号自DEFAULT_ADB_LOCAL_TRANSPORT_PORT起自增2client_socket_thread又被local_init调用。在adb.cadb_main函数对ADB HOST调用了local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT)

     

    ddmlib这个库被许多Android工具所使用,比较有名的有ddmsEclipse ADT插件集成)、hierarchyviewer,它没有重用连接只有有指令就会创建一个新的adb连接很容易使得多台机器连接出不稳定的情况,亲见过hierarchyviewer在连接很多台手机时刷新很慢很慢、Eclipse在控制台输出许多连接被拒的信息。如Dalvik Debug Monitor ServiceDDMS)在单个PC上同时连接多个手机设备会超时,这主要源自文件AdbHelper.java中函数executeRemoteCommandmaxTimeToOutputResponse进行超时判断, 超时则抛出ShellCommandUnresponsiveException异常;在Device.javamaxTimeToOutputResponse被赋值为DdmPreferences.getTimeOut()DdmPreferences定义在文件DdmPreferences.java中,其函数getTimeOut返回sTimeOut,而sTimeOut被赋值为DEFAULT_TIMEOUT,在文件DdmPreferences.javaDEFAULT_TIMEOUT固定为5000毫秒。

     

    所以当16+设备连接到单台pc上时不要开Eclipseddmshierarchyviewer、豌豆荚和91手机助手 for Android,用线程池控制最大16个并发,每个并发代表一台设备,每个并发中一条指令执行完后顺序执行下条指令。除了这个并发,还有两个问题:1.adb devices列举的设备数不稳定,测试过程中出现有时多有时少,有时能列全连接的设备有时又不能,目前的处理是连续多次运行adb devices把每次列举出的设备都记录最后保留最大数字的那个,目前的多次是12次;2.指令连接设备的过程中会出现异常:a.设备offline b.设备对指令无响应,对b异常目前是设置了等待超时,超时后杀掉abd并记录该操作步骤失败设置该测试用例失败,远期会实现补救因为发现了现象:先执行adb kill-server,再adb devices两次之后会连接上原先断开的设备,这个重试的时机应该放在所有正常的设备自动化测试都做完之后进行,以免影响正常自动化测试的执行。目前采取的连接30台设备到一台PC的策略是:用Ubuntu Linux连接设备以避免安装驱动,但还是有部分设备还得在Windows下连接,如中兴 U880在Ubuntu下用命令usb devices无法显示设备号,华为C8500和Vodafone 845在Ubuntu下用命令usb devices显示设备号为“????????????”,但用命令连接设备时“adb –s ???????????? shell”无法连接上。

     

    关于adb的延伸阅读见浅析linux开发工具adb具体实现再次浅析adb shell,pc daemon和手机daemon三者之间的数据交互流程浅析adb创建流程。命令行驱动adbADBCommandAndroid运行shell或者一个可执行程序。线程池直接用Java自带的java.util.concurrent.Executors.newFixedThreadPool

     

    另外,Android 3.1+引入了USB Host,具体使用见Android Usb Host Tutorial - AdbTest

  • 2011年09月01日

    APK 签名

    分类:

    APK Crack(Auto sign multiple APKs and ZIPs)

    Android APK 签名比对

    Android学习系列(1)--App签名(apk签名)

    关于apk签名

    简单分辨APK签名

    重新签名APK文件

    如何导出一个未签名的APK文件?

     

    Android默认的debug签名目录可以通过Eclipse里的Window->Preferences->Android->Build->Default debug keystore里找到。

  • 2011年08月05日

    Android 屏幕分辨率

    分类:

    术语

    • 分辨率:Resolution,即屏幕物理像素总数
    • 屏幕密度:Screen density,屏幕可见区域的像素数也叫dpi(dots per inch)即每英寸的像素数
    • 密度无关像素:Density-independent pixel(dp),这是一个虚拟的像素单位,用于定义UI布局,以密度无关的方式表达布局的维度和位置
    • VGA:Video Graphics Array,即视频图形阵列
    • QVGA:Quarter VGA即VGA的四分之一
    • WQVGA:Wide Quarter VGA;即扩大的QVGA,分辨率比QVGA高但比VGA低
    • HVGA:Half-size VGA,即VGA的一半
    • WVGA:Wide Video Graphics Array,即扩大的VGA
    • FWVGA:Full Wide VGA,是扩大了WVGA,分辨率比WVGA高
    • SVGA:Super Video Graphics Array,即高级视频图形阵列
    • WSVGA:Wide Screen Video Graphics Array,即SVGA的宽屏版,多用于超便携移动个人电脑(Ultra-Mobile PC,abbre. UMPC)、上网本和平板电脑中,也有手机如三星Galaxy Tab
    • XGA:Extended Graphics Array,即扩展图形阵列,多用于笔记本和投影机
    • WXGA:Wide eXtended Graphics Array,即XGA的宽屏版本,多用于宽屏笔记本
    • qHD:Quarter High Definition(FULL HD 1920×1080的四分之一),代表960X540(宽高比16:9)的屏幕分辨率,是高清屏

     

     Android 屏幕分辨率

    名称QVGAWQVGAHVGAVGAWVGAFWVGASVGAWSVGAXGAWXGAqHD
    屏幕分辨率(像素) 320×240(4:3) 384×240(8:5) 480×272(16:9) 320×200(16:10) 800×480(15:9) 854×480(16:9) 800×600(4:3) 1024×576(16:9) 640×480(4:3) 1280×720(16:9) 960×540(16:9)
      400×240(5:3) 480×320(3:2) 640×350(64:35) 848×480(53:30)     1024×600(16:9) 800×600(4:3) 1280×768(15:9)  
      432×240(9:5) 480×360(4:3) 640×480(4:3) 854×480(16:9)       1024×768(4:3) 1280×800(16:10)  
      480×272(16:9) 640×240(8:3) 720×400(9:5)           1360×768(16:9)  
                      1366×768(16:9)  

    Android SDK模拟器能够模拟上表的几种配置,见screens_support

  • 2011年08月04日

    Android Instrumentation 实现

    分类:

    先前以为Android Instrumentation的实现利用了java的语法特性,今天发现不是。

     

    Instrumentation.java

    start -> InstrumentationThread -> ActivityManagerNative.getDefault

     

    ActivityManagerNative.java

    getDefault -> ServiceManager.getService("activity");

    onTransact -> START_INSTRUMENTATION_TRANSACTION -> startInstrumentation-> mRemote.transact(START_INSTRUMENTATION_TRANSACTION, data, reply, 0);

     

    Binder.java

    transact -> onTransact

     

    IPCThreadState.cpp

    transact

     

    实际上这种绑定javaC++都实现了,通过IPC进行通信。

  • 2011年08月04日

    Android 屏幕截图

    分类:

    adb shell进入同手机远程交互,命令getprop(位于android系统\system\bin\)可查看机器的全部参数信息,getprop ro.build.version.sdk可查看机器用的sdk版本,getprop ro.build.version.release可查看机器android系统版本号。

     

    国内的开源中国社区提供了网页android源码查看android-2.2-froyoAndroid中的测试代码主要来自junit框架里的TestSuite,包括InstrumentationTestSuiteInstrumentationTestCaseInstrumentationTestRunnerInstrumentationandroid.app.Instrumentation)是其测试框架的核心,它能在测试代码中引发回调方法。其发布时需要签名

     

    DDMS对手机设备截屏,这是通过ddmlib这个库实现的,这个功能的调用源码码位于\development\tools\screenshot\src\com\android\screenshot\monkeyrunner中的MonkeyImage也实现了,它的截图调用包com.android.chimpchat.core.IChimpImage来实现,它的调用链为device.getScreenshot() -> AdbHelper.getFrameBuffer -> formAdbRequest("framebuffer:")android系统源码中adb目录(/platform/system/core/adb)下的services.c比较出”framebuffer:”之后创建服务进程framebuffer_serviceframebuffer_service.c),从这里打开设备“/dev/graphics/fb0”,调用这个设备见FrameBuffer中获取Android屏幕截图因为READ_FRAME_BUFFER需要签名权限,这个操作需要同应用程序权限来读取这个流,碰巧此处的应用程序是android系统即需要系统映像签名,而adb有这个权限。

     

    通过命令行直接向该设备要帧截图,可参考Taking screenshots with an Android ADBCapturing images in Android framebuffer

     

    adb 通信协议SERVICES.TXT列举了adb.exe的全部参数。

     

    Seleniumandroid截图调用api: android.webkit.WebView.capturePicture()抓取整个网页,在currentView.capturePicture()这里被调用,然后在函数screenshot()中对它进行裁剪只显示屏幕上可见的部分。