为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > Android帮助文档(第二部分)开发工具

Android帮助文档(第二部分)开发工具

2011-12-05 31页 doc 290KB 58阅读

用户头像

is_146971

暂无简介

举报
Android帮助文档(第二部分)开发工具Android帮助文档(第二部分)开发工具 2一、Android Emulator 2Android模拟器 5使用模拟器控制台 7SD卡模拟 7故障排除 8模拟器的限制 8二、Android Development Tools Plugin for the Eclipse IDE 8三、Dalvik Debug Monitor Service(ddms) 9使用Dalvik调适监视器服务工具 11四、Android Debug Bridge (adb) 12启动和终止adb系统 1...
Android帮助文档(第二部分)开发工具
Android帮助文档(第二部分)开发工具 2一、Android Emulator 2Android模拟器 5使用模拟器控制台 7SD卡模拟 7故障排除 8模拟器的限制 8二、Android Development Tools Plugin for the Eclipse IDE 8三、Dalvik Debug Monitor Service(ddms) 9使用Dalvik调适监视器服务工具 11四、Android Debug Bridge (adb) 12启动和终止adb系统 12安装应用程序 12打印内核信息 12发布shell命令 13端口转发 13复制文件 13询问设备状态/建立辅助设备和仿真器列表 14获得Debug信息 14创建射频日志 14等待设备状态改变 14获取id或者序列号 14检查sqlite数据库 14五、Android Asset Packaging Tool (aapt) 15六、Android Interface Description Language (aidl) 15使用AIDL实现IPC 20调用一个IPC方法 23七、sqlite3 23八、traceview 23Creating Trace Files 建立跟踪文件 24Copying Trace Files to a Host Machine 拷贝跟踪文件到主机 24Viewing Trace Files in Traceview 使用Traceview查看跟踪文件 25Data File Format Data文件格式 25Key File Format Key文件格式 26Traceview Known Issues Traceview存在问题 27Using dmtracedump dmtracedump用法 一、Android Emulator Android模拟器 Android SDK自带一个移动设备模拟器 — 它是一个可以运行在你电脑上的虚拟设备. Android模 拟器可以让你不需使用物理设备即可预览、开发和测试Android应用程序. Android模拟器能够模拟除了接听和拨打电话外的所有移动设备上的典型功能和行为. 如右图所示, Android模拟器提供了大量的导航和控制键,你可以通过鼠标或键盘点击这些按键来为你的应用程序产生 事件. 同时它还有一个屏幕用于显示Android自带应用程序和你自己的应用程序. 为了便于模拟和测试应用程序, Android模拟器允许你你的应用程序通过Android平台服务调用其他程 序、访问网络、播放音频和视频、保存和接收数据、通知用户、渲染图像过渡和场景. Android模拟器同样具有强大的调试能力,例如能够记录内核输出的控制台、模拟程序中断(比如接受 短信或打入电话)、模拟数据通道中的延时效果和遗失。 下面的章节将提供关于模拟器的详细信息,以及如何在开发应用程序中使用模拟器。 http://code.google.com/android/images/emulator-hvga-p.png 启动和关闭模拟器 要启动Android模拟器,首先进入SDK的tools/文件夹,然后输入 emulator 或 ./emulator。这个操作将初始化Android系统,你将会在屏幕 上看到模拟器窗口。 要关闭模拟器,只需要关闭模拟器窗口即可。 操作模拟器 你可以通过模拟器的启动选项和控制台命令来控制模拟环境的行为和特性。一旦模拟器启动,你就可以通过键盘和鼠标来"按" 模拟器的按键,从而操作模拟器。 下面的表格总结了模拟器按键可键盘按键之间的映射关系。 模拟器按键 键盘按键 后退 ESC 菜单 F1 或 PgUp 开始 F2 或 PgDn 呼叫 F3 挂断 F4 --- F5, F6 未分配 电源按键 F7 禁用/启用所有网络 F8 开始跟踪 F9 (当且仅当有-trace标记时有效) 停止跟踪 F10 (当且仅当有-trace标记时有效) 主页 HOME 方向键 左/上/右/下 小键盘 4/8/6/2 方向键 中心建 小键盘 5 调低音量 小键盘 负号(-) 调高音量 小键盘 加号(+) 模拟器启动选项 Android模拟器提供了很多启动选项,你可以在启动模拟器时指定,来控制其外观和行为。下面是用命 令行的方式启动模拟器并指定参数的语法: emulator [-option [value]] ... [-qemu args] 下表总结了所有有效的选项。 类型 选项 描述 注释 帮助 -help 以列表的形式打印模拟器的所有命令   数据 -data [file] 使用当作用户数据的磁盘镜像 如果没有-data,模拟器会在~/.android (Linux/Mac) 或C:\Documents and Settings\\Local Settings\Android (Windows)中查找文件名为"userdata.img"的文件。 如果使用了-data 不存在,模拟器会在那个位置创建一个文件 -ramdisk 使用作为RAM镜像 默认值为/ramdisk.img -sdcard 使用 作为SD卡镜像 默认值为/sdcard.img -wipe-data 启动前清除用户磁盘镜像中的所有数据(参考-data)   调试 -console 允许当前中断使用控制台Shell   -debug-kernel 将内核输出发送到控制台   -logcat 允许根据给定的标签为输出分类 如果定义了环境变量ANDROID_LOG_TAGS并且不为空, 它的值将被作为logcat的默认值。 -trace 允许代码剖析(按F9键开始)   -verbose 允许详细信息输出   -verbosekeys 允许详细输出按键信息   媒体 -mic 使用设备或者WAV文件作为音频输出   -noaudio 禁用Android的音频支持 默认禁用 -radio 将无线调制解调器接口重定向到主机特征设备   -useaudio 启用Android音频支持 默认不启用 网络 -netdelay 设置网络延迟模拟的延迟时间为. 默认值是none。请参考网络延迟模拟中表"支持的值" -netfast -netspeed full -netdelay none的快捷方式   -netspeed 设置网速模拟的加速值为. 默认值为full。请参考网速模拟中表"支持的值" 系统 -image 使用作为系统镜像 默认值为/system.img -kernel 使用 作为模拟器内核   -nojni   -qemu 传递qemu参数   -qemu -h 显示qemu帮助信息 -system 目录下查找系统、RAM和用户数据镜像   UI -flashkeys 在设备皮肤上闪烁按下的键   -noskin 不使用任何模拟器皮肤   -onion 在屏幕上使用覆盖图 不支持JPEG格式图片,仅支持PNG格式图片 -onion-alpha 指定onion皮肤的半透明值(单位%). 默认值为50 -skin 用指定皮肤启动模拟器 SDK提供了4个可选皮肤:  QVGA-L (320x240, 风景) (默认)  QVGA-P (240x320, 肖像)  HVGA-L (480x320, 风景)  HVGA-P (320x480, 肖像) -skindir 目录下查找皮肤 使用模拟器控制台 每一个运行中的模拟器实例都包括一个控制台,你可以利用控制台动态的查询和控制模拟设备的环境 。例如,你可以利用控制台动态的管理端口映射和网络特性,还可以模拟电话时间。要想进入控制台输入 命令,你需要使用telnet连接到控制台的端口号。 你可以使用下面的命令随时随地连接到任何一个运行中的模拟器实例: telnet localhost 假设第一个模拟器实例的控制台使用5554端口,下一个实例使用的端口号会加2,比如5556、5558…… 等。你可以在启动模拟器是使用-verbose选项来检测该模拟器实例使用的端口号,在调试 输出的找到以"emulator console running on port number"这一行。 另外, 你可 以在命令行中使用adb devices来查看模拟器实例和他们的端口列表。最多可以有16个模拟 器实例同时运行控制台。 注意:模拟器监听端口5554-5587的来自任何电脑的连接。将来发布的版本将只接受本 机的连接,但目前,你需要用防火墙阻断外部对你开发设备的5554-5587这些端口的连接。 一旦连接上控制台, 你可以输入help [command]来查看命令列表和指定命令的教程。 要离开控制台会话, 使用quit 或 exit 命令。 下面的章节将介绍控制台的主要功能区域。 使用模拟器皮肤 你可以让模拟器使用下表介绍的4种皮肤之一。要想指定皮肤,在启动模拟器是使用-skin 选项。 例如: emulator -skin HVGA-L 注意: 必须用大写(如果你的开发设备大小敏感)。 皮肤ID 描述 皮肤 QVGA-L 320x240, 横屏 (默认) http://code.google.com/android/images/e-mini-qvga-l.png QVGA-P 240x320, 竖屏 http://code.google.com/android/images/e-mini-qvga-p.png HVGA-L 480x320, 横屏 http://code.google.com/android/images/e-mini-hvga-l.png HVGA-P 320x480, 竖屏 http://code.google.com/android/images/e-mini-hvga-p.png 运行多个模拟器实例 如果必要的话,你可以同时运行多个模拟器实例。每个模拟器实例使用独立的用户数据内存和不同的 控制台端口。这令你可以独立的管理每一个模拟器实例。 然而,如果你要运行多个模拟器实例,请注意每个实例存储跨会话的持久用户数据的能力—用户 设置和安装的应用程序—会受限制。具体如下: · 只有第一个模拟器实例能根据会话保存用户数据。默认情况下它把用户数据保存在开发设备 的~/.android/userdata.img (on Linux and Mac) 或 C:\Documents and Settings\\Local Settings\Android\userdata.img (on Windows)文件里。你可以 在启动模拟器时使用-data选项来控制用户数据的存储(和加载)位置(请参考启动选项)。 · 在第一个实例后启动的模拟器实例(并行的)在会话过程中也保存用户数据;但它们but they 不 为下一个会话保存它。这些实例将数据保存在临时文件中,当实例退出时,相应的临时文件会被删除。 在模拟器上安装应用程序 要想在模拟器上安装应用程序安装,要用到adb工具。 注意:模拟器通过重启保存用户设置和安装的程序。默认情况下,模拟器将数据保存在开发设备的一 个文件里。在Linux和Mac操作系统下,模拟器将用户数据报讯在~/.android/userdata.img 。在Windows下,模拟器将数据保存在C:\Documents and Settings\\Local Settings\Android\userdata.img。模拟器用userdata.img文件的内容作为data/的 目录。 SD卡模拟 你可以创建磁盘镜像并在模拟器启动时加载它,来模拟设备中用户的SD卡。下面的章节将介绍如何创 建磁盘镜像、如何向磁盘镜像像拷贝文件和如何在模拟器启动时加载镜。 注意:只能在模拟器启动是加载磁盘镜像。同理,模拟器运行时不能移除SD卡。然而,你可以通过adb 或模拟器浏览、发送、拷贝和删除模拟SD卡上的文件。 同时还要注意,模拟SD卡的大小不能超过2GB。 创建磁盘镜像 你可以用SDK中的mksdcard工具来创建可以在模拟器启动时加载的FAT32磁盘镜像。你可以在SDK的 tools/目录下找到mksdcard,用下面的命令船检磁盘镜像: mksdcard 更多信息,请参考其他工具。 拷贝文件到磁盘镜像 一旦你创建了一个磁盘镜像,你就可以在模拟器加载它之前拷贝文件到镜像中。要拷贝文件,你可以 将镜像加载为循环设备然后向里面拷贝文件,或者你可以使用mtools工具包中的mcopy直接将文件拷贝到 镜像中。mtools包在Linux、Mac和Windows下均可用。 在模拟器启动时加载磁盘镜像 要想在模拟器中加载FAT32格式的磁盘,启动模拟器时带上-sdcard标记并指定镜像的名 称和路径(相对于当前工作目录): emulator -sdcard 故障排除 adb工具把模拟器当成是一个真实的物理设备。因此,你需要在使用adb命令--例如 install--时加上-d标记。-d 标记允许你在众多连接设备中指定使用哪一个设备作为命令 的目标。如果不指定-d,模拟器会选择列表中的第一个设备。向了解更多关于adb的信息,请参考 Android Debug Bridge。 对于运行在Mac OS X上的模拟器,如果你在启动模拟器时遇到"Warning: No DNS servers found"错误,请查/etc/resolv.conf文件是否存在。如果不存在,请在命令窗口中运行下面的命令 : ln -s /private/var/run/resolv.conf /etc/resolv.conf 请参考常见问题回答获得更多故障 排除信息。 模拟器的限制 这一版的模拟器存在如下限制: · 不支持呼叫和接听实际来电;但可以通过控制台模拟电话呼叫(呼入和呼出) · 不支持USB连接 · 不支持相机/视频捕捉 · 不支持音频输入(捕捉);但支持输出(重放) · 不支持扩展耳机 · 不能确定连接状态 · 不能确定电池电量水平和交流充电状态 · 不能确定SD卡的插入/弹出 · 不支持蓝牙 二、Android Development Tools Plugin for the Eclipse IDE 用于Eclipse集成开发环境的Android应用开发工具插件:它为Eclipse集成开发环境增加了强大的功能,使得创建和调试Android应用程序更加简单和快速。如果你使用Eclipse来开发Android应用,ADT插件将给你带来极大的帮助: · 可以从Eclipse集成开发环境内部访问别的Android开发工具。例如,ADT允许你直接从Eclipse访问DDMS工具的很多功能,包括截屏、管理端口转发(port-forwarding)、设置断点、查看线程和进程信息。 · 它提供一个新的项目向导,用于快速创建一个新的Android应用需要的所有基本文件。 · 它使构建Android应用的过程自动化和简单化。 · 它提供一个Android代码编辑器,用于为Android的manifest和资源文件编写有效的XML。 更多的关于ADT插件的信息,包括安装指令,请参见Installing the ADT Plugin for Eclipse。Hello Android描述了一个有用的例子程序和程序的效果图。 三、Dalvik Debug Monitor Service(ddms) Dalvik调试监视服务:它集成在Dalvik(Android平台的虚拟机)中,用于管理运行在模拟器或设备上的进程,并协助进行调试。你可以用它来杀死进程、选择一个特定程序来调试、生成跟踪数据、查看堆和线程数据、对模拟器或设备进行屏幕快照等等。 使用Dalvik调适监视器服务工具 Android附带了一个调试工具, 叫做Dalvik 调适监视器服务(DDMS), 提供了端口转发服务, 手机设备屏幕截图, 设备上的线程和堆栈信息, 日志, 进程, 射频状态信息, 以及更 多的功能. DDMS 位于SDK主目录下的tools目录中; 在该目录的命令控制台输入ddms(小写)即可运行DDMS. DDMS可以配合模拟器或设备使用; 如果模拟器和设别同时被连接并且同时 在运行, DDMS默认会连接模拟器. 该文档对DDMS的功能做了简要的介绍; 这里没有对DDMS的特性和功能做过与详细的解释. 你可以对DDMS进行一些设置, 点击菜单中的File->Preferences即可开始设置, 设置文件存放在"$HOME/.ddmsrc"目录下. 左下角面板 左侧窗口中的列表显示了DDMS找到的设备或模拟器中的所有虚拟机(VM). 虚拟机用它的应用的包名来标识; 如果有多个Activities 在一个包内, 他们会在同一个虚拟机内运行. 利 用该列表找到你想调试的activity, 在该列表中, 每个虚拟机的前面会显示"调试端口"的端口号; 如果你使用调试器链接这些端口, 就相当于链接了该设备中相应的虚拟机. 一个 不错的特性是, Dalvik 还为当前被选择的虚拟机分配了一个附加端口号, 8700. 这个默认的"当前选择"端口可以让你在切换应用的时候不必重新配置调试端口(就是说调试器链接 8700, 之后不管你切换到哪个虚拟机, 8700都是你当前选择的虚拟机的调试口). 当一个运行在虚拟机中的应用执行了waitForDebugger()(或者你在手机的developer选项里面选择 了这项), 一个红色的图标会在客户端的名字后面显示, 当一个调试器链接上之后, 这个图标会变成绿色. DDMS的一些标签页显示了当前需选择的虚拟机的有用信息: 信息标签页 这个标签页显示了所选虚拟机的常用信息, 包括进程的ID, DDMS链接的端口号. 这个不是您在IDE里面配置的那个端口号. 另外, 在虚拟机的列表页面的中, 当前所选的虚拟机也会同样将端口信息转发到8700端口, 使用这个"当前选择"端口, 避免您在调适多个Activities时重新配置eclipse的端口信息 .(该"当前选择"端口号可以在"preferences"对话框中设置.) 线程标签页 线程标签页显示了在目标虚拟机中当前进程中的所有线程信息. 为了减少数据传输, 仅仅在工具栏的"threads"被按下时设备才会发送线程的信息. 每一个虚拟机都有一个按钮开关 , 该标签页显示了如下信息: · ID - 虚拟机分配的唯一线程ID. 在 Dalvik, 该数字是一个从3开始的奇数. · Tid - Linux 线程 ID. 进程中主线程的ID, 会同进程的ID相匹配. · 状态 - 虚拟机线程状态. 守护进程会附带一个'*'. 状态信息列表如下: · running - 正在执行应用程序 · sleeping - 执行了Thread.sleep() 方法 · monitor - 在正等待获取一个监听锁 · wait - 在Object.wait() 方法中 · native - 执行了原生代码 · vmwait - 正在等待一个虚拟机资源 · zombie - 该线程已死 · init - 线程正在初始化 (你不会看到这个) · starting - 线程正在启动中 (这个你也不会看到) · utime - 执行用户代码的累计时间, 单位为"jiffies(表示系统启动以来的tick数)" (通常是 10ms). 仅在Linux系统中适用. · stime - 执行系统代码的累计时间, 单位为"jiffies(表示系统启动以来的tick数)". · 名字 - 线程的名字 "ID" 和 "Name" 在进程启动的时候就会显示. 其余的字段每个一段时间更新一次(默认是4秒钟) 堆标签页 显示内存堆的状态信息, 每次垃圾回收的时候更新. 端口转发(调试器链接到设备) DDMS扮演了IDE和设备上运行的应用的中间人角色. Android持有多个进程, 每一个进程都有自己的虚拟机. 每一个应用运行在自己的进程中. 每个进程都有一个唯一的调试监听端口: 第一个进程的调试监听端口是8000, 下一个是8001, 依次向下. DDMS默认情况下会扫描设备上的8000-8019端口, 并且每两秒扫描一次, 以获取新的进程信息(你可以在DDMS的配置页改变这些信息). 当DDMS检测到一个虚拟, 他会链接到调试端口并且开始发送请求信息. DDMS和Dalvik 通过一个自定义的有线通信来相互联系. 链接建立之后, 他就开始把信息转发到你的IDE能够接受的端口, 以显示出来, 你的IDE会使用8700端口来进行调试. 调试Dalvik时会出现的已知问题 当single-stepping 与代码不同步的时候, 点击下一个step之后, 显示当前行的光标可能会直接跳到方法的最后一行. 截图 您可以截取设备或虚拟机屏幕, 选择主菜单中的Device > Screen capture. 进程信息查看 你可以查看指定虚拟机中 ps -x命令的输出, 在主菜单选择Device > Show process status. 手动垃圾回收 点击工具条的GC按钮, 会引发一个垃圾回收操作. 在设备上执行 Dumpsys 和 Dumpstate (logcat) 执行Dalvik的dumpsys(logcat)命令, 选择主菜单的Device > Run logcat... 执行Dalvik的dumpstate命令, 选择主菜单的Device > Dump device state... 检查射频状态 默认情况下, 射频的状态信息是不会输出的(因为这个信息非常多). 若想查看该信息, 点击Device > Dump radio state... 或是像记录射频日志中描述那样执行logcat. 停止虚拟机 你可以通过选择菜单中的Actions > Halt VM来停止一个虚拟机, 点击该按钮相当于让虚拟机执行System.exit(1). DDMS的已知问题 DDMS目前有下列已知问题: · 如果你链接和断开一个调试器, ddms 断开和重连客户端时, 虚拟机会认为调试器已经失去连接了. 这个问题最终会解决. · 不要尝试让ddms链接一个运行在Sun Java 桌面虚拟机, 这样会引起崩溃. 四、Android Debug Bridge (adb) Android调试桥:它用于向模拟器或设备安装应用程序的.apk文件和从命令行访问模拟器或设备。也可以用于将标准的调试器连接到运行在Android模拟器或设备上的应用代码。 Android Debug Bridge Android Debug Bridge (adb)是通用的debug工具,使你管理设备或者仿真器的状态.它包括运行在后台预定程序下做为连接主机,仿真器,其他设备之间端口的一个 daemon. 与命令行接口一样通过控制daemon.仿真器和其它设备.在其他使用当中,adb使你能够: 快速更新设备或者仿真器代码,例如应用程序或Android系统程序的更新 在设备上运行shell命令 在仿真器或设备上面管理预定端口 仿真器或设备上同步文件 以上部分定义在adb使用命令当中 启动和终止adb系统 使用adb命令来启动.daemon启动自动使用默认端口5037.注意:当你运行多个仿真器的时候,adb只能连接第一个启动的实例. 如何要终止adb,使用命令 adb kill-server 安装应用程序 从主机程序(.apk)安装到仿真器或者设备,使用命令: adb install 打印内核信息 打印内核信息命令: adb shell dmesg 发布shell命令 可以用adb进入设备或者仿真器的shell.使用命令: adb shell CTRL+D或者exit命令退出. 对于单行shell命令,可以快速的执行: adb shell [command] 端口转发 可以使用adb设置访问主机的端口,这些特殊的端口会转发给仿真器或设备上. 例如主机端口5555 转发给 仿真器/设备上8000端口的命令: adb forward tcp:5555 tcp:8000 同样,可以用adb设置UNIX domain sockets抽象名称转发: adb forward tcp:5556 local:logd 复制文件 可以复制道设备上面用文件,用adb命令.也可以复制文件或者目录到仿真器或者设备上面,使用: adb push 也可以从仿真器或设备上面得到文件或者目录,使用 adb pull 下面是简单的例子: adb push foo.txt /tmp/foo.txt adb pull /android/lib/libwebcore.so . 询问设备状态/建立辅助设备和仿真器列表 要得到运行在当前仿真器/设备实例状态列表,命令: adb devices adb返回状态,类型和数量.如果没有运行仿真器/设备,adb返回结果会提示没有找到当前设备. adb返回状态列表: |id|serial #|type|lock| where type can be either device (connected via adb) or offline (not connected via adb). 例如adb的输出: $ adb devices List of devices attached 6 emulator-tcp-5555 device 0 获得Debug信息 你可以运行debug命令清除系统和清除状态在adb shell.我们建议使用Dalvik Debug Monitor Server (DDMS) debug工具来直接清除adb shell下面的系统和状态.运行DDMS并且从设备菜单里选择清除设备状态来显示状态信息。从DDMS设备菜单里检索清楚系统信息,选择"Run logcat"。下一步,退出adb shell下清除系统命令。信息将显示在Dalvik窗口下。 创建射频日志 默认的射频信息没有日志,所有想要记录射频信息的话,要如下操作: adb shell logcat -b radio 等待设备状态改变 你可以运行命令去等候连接正在运行的设备: adb wait-for-device 获取id或者序列号 如下命令可以得到设备的ID或者序列号. adb get-product adb get-serialno 检查sqlite数据库 另外的,Android SDK包括sqlite3,用于管理SQLite数据库命令命令行程序(例如通过Android程序来创建).sql3 工具包括大量有用的命令,例如 .dump 打印表格目录. .schema 打印SQL 以有表的创建状态.这个工具也可以用在移动设备上执行命令. 启动sqlite3,进入adb shell和sqlite3类型,遵循你想要的数据库的全路径名.在仿真器或者设备上的数据库存储目录 /data/data//databases/. 五、Android Asset Packaging Tool (aapt) Android资源打包工具:你可以通过aapt工具来创建.apk文件,这些文件包含了Android应用程序的二进制文件和资源文件。 使用aapt aapt即Android Asset Packaging Tool , 在SDK的tools/目录下. 该工具可以查看, 创建, 更新ZIP格式的文档附件(zip, jar, apk). 也可将资源文件编译成二进制文件. 尽管你可能没有直接使用过aapt工具, 但是build scripts和IDE插件会使用这个工具打包apk文件构成一个Android 应用程序. 获取更多的实用信息, 请打开终端控制台, 到tools/目录下, 执行命令: · Linux or Mac OS X: ./aapt · Windows: aapt.exe 六、Android Interface Description Language (aidl) Android接口描述语言:它用来生成进程间接口代码。例如,在一个服务中可能就会用到。 使用AIDL(AndRoid接口描述语言)设计和使用远程接口 通常每个应用程序都在它自己的进程内运行,但有时需要在进程间传递对象,你可以通过应用程序UI的方式写个运行在一个不同的进程中的 service。在AndRoid平台中,一个进程通常不能访问其他进程中的内存区域。所以,他们需要把对象拆分成操作系统能理解的简单形式,以便伪装成对象跨越边界访问。 编写这种伪装代码相当的枯燥乏味,好在我们提供了AIDL工具可以来做这件事。 AIDL(AndRoid接口描述语言)是一个IDL语言,它可以生成一段代码,可以使在一个AndRoid设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。 AIDL IPC的机制是基于接口的,和COM或Corba类似,但它是轻量级的。它使用代理类在客户端和实现层间传递值。 本页包含以下主题: 使用AIDL实现IPC 调用一个AIDL(IPC)类 使用AIDL实现IPC 使用AIDL实现一个IPC有下列步骤: 1、创建你的AIDL文件 - 这个文件定义一个接口(YourInterface.aidl),该接口定义了可供客户端访问的方法和属性。 2、添加AIDL文件到你的makefile中-(Eclipse plugin可以帮你管理)。AndRoid包括编译器,AIDL调用,这些都能在tools/directory中找到。 3、实现接口方法-AIDL编译器从你的AIDL接口中使用JAVA编程语言来创建一个接口。这个接口有一个名为Stub的内部抽象类,它继承接口(并实现供IPC调用的所必需的几个附加方法)。你必须创建一个类来实现该接口。 4、向客户端开放接口-如果你写个service,你应该扩展该Service并重载getBinder()方法来返回一个实现上述接口的类的实例。 创建一个AIDL文件 AIDL语法简单,你可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。这些参数和返回值可以是任何类型,甚至是其他的AIDL生成的接口。然而,值得重视的是你必须导入所有的non-bult-in类型,即使他们已经作为接口在其他包里定义了。下面是些AIDL支持的数据类型: 简单Java编程语言类型(int,boolean等) -不需要import声明。 下面类之一(不需要import声明)。 .String .List - All elements in the List must be one of the types in this list, including other AIDL-generated interfaces and parcelables. List may optionally be used as a "generic" class (e.g. List). The actual concrete class that the other side will receive will always be an ArrayList, although the method will be generated to use the List interface. .List - List中的所有元素都必须是可支持的类型中的一个,包括其他AIDL生成接口和parcelables。List可以作为泛型类来灵活使用(比如 List)。而实际的接受方的类则总是ArrayList,尽管该方法将被生成来使用List接口。 .Map - All elements in the Map must be of one of the types in this list, including other AIDL-generated interfaces and parcelables. Generic maps, (e.g. of the form Map are not supported. The actual concrete class that the other side will receive will always be a HashMap,although the method will be generated to use the Map interface. .Map - Map中的所有元素都必须是可支持的类型中的一个,包括其他AIDL生成接口和parcelables。泛型化的Maps(比如:Map)不被支持。 而实际的接受方的类则总是HashMap,尽管该方法将被生成去使用Map接口。 .CharSequence - This is useful for the CharSequence types used by TextView and other widget objects. .CharSequence - CharSequence的作用是可以被TextView和其他Widget对象使用。 其他的AIDL生成接口通过引用方式进行传递。所以import声明是必须的。封装协议实现的自定义的类是值传递的方式。所以import声明也是必须的。 下面是基本的AIDL语法: // My AIDL file, named SomeClass.aidl // Note that standard comment syntax is respected. // Comments before the import or package statements are not bubbled up // to the generated interface, but comments above interface/method/field // declarations are added to the generated interface. // Include your fully-qualified package statement. package com.google.android.sample; // See the list above for which classes need // import statements (hint--most of them) import com.google.android.sample.IAtmService; // Declare the interface. interface IBankAccountService { // Methods can take 0 or more parameters, and // return a value or void. int getAccountBalance(); void setOwnerNames(in List names); // Methods can even take other AIDL-defined parameters. BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService); // All non-Java primitive parameters (e.g., int, bool, etc) require // a directional tag indicating which way the data will go. Available // values are in, out, inout. (Primitives are in by default, and cannot be otherwise). // Limit the direction to what is truly needed, because marshalling parameters // is expensive. int getCustomerList(in String branch, out String[] customerList); } 实现接口 AIDL生成一个接口文件,文件名和你的AIDL文件名一致。如果你使用的是Eclipse插件,AIDL会作为build过程的一部分自动运行(你不需要首先运行ADIL然后再去创建你的项目)。否则的话,你需要首先运行AIDL。 生成的接口包括一个名为Stub的内部抽象类,该类声明了你在aidl文件中声明的所有方法。Stub也定义几个有用的方法,最特别的是asInterface(),它执行一个IBinder(在 applicationContext.bindService()执行成功后传给客户端onServiceConnected()方法),并返回一个用来调用IPC方法的接口实例。更多细节请查看章节调用IPC方法。 实现接口,扩展YourInterface.Stub,并实现方法成员。(你可以创建一个aidl文件并实现stub方法而不用绑定-AndRoid创建过程在java文件之前会处理aidl文件)。 这里有个例子,它实现了一个调用IRemoteService的接口,并使用匿名实例公开一个简单的方法gerPid(): // No need to import IRemoteService if it's in the same project. private final IRemoteService.Stub mBinder = new IRemoteService.Stub(){ public int getPid(){ return Process.myPid(); } } 实现接口时有几个原则: .抛出的异常不要返回给调用者。 .IPC调用是同步的。如果你知道一个IPC服务需要超过几毫秒的时间才能完成地话,你应该避免在Activity/View线程中调用。 因为它会挂起应用程序(AndRoid可能会显示"应用程序没有响应"对话框)。试着在一个独立的线程中调用。 .只有方法才获得支持;你不能在AIDL接口中声明静态属性。 向客户端公开接口 现在你已完成了接口的实现,你需要向客户端公开该实现。这就是我们所熟悉的"发布服务"。发布一个Service,然后继承 Service并实现getBinder()返回一个实现的类的实例。下面是个Service的代码片断,该Service向客户端公了 IRemoteService接口。 public class RemoteService extends Service { ... @Override public IBinder getBinder() { return mBinder; } /** * The IRemoteInterface is defined through IDL */ private final IRemoteService.Stub mBinder = new IRemoteService.Stub() { public int getPid() { return Process.myPid(); } }; } 使用parcelables进行参数的值传递 警告:如果你现在使用Eclipse插件,Parcelables并不能工作。你会看到以下的错误信息: .仅声明parcelables的.aidl文件不需要写进makefile .aidl只能生成接口代码,而不是parcelables。 这是个众所周知的局限。Parcelables仍然可以被ant build的xml文件或自定义的build系统所使用。你应该在Eclipse项目中添加一个工作区,该工作区可以为所有的接口手动运行aidl工具。下面的步骤5说明为何Eclipse不该尝试编译这些aidl文件。 如果你有类需要通过AIDL接口从一个进程发送到另一个,你必须确保类代码可以被IPC接收端所使用。通常这意味着一开始你就要和service进行通讯。 让类支持parcelable协议,有五点需要注意 1. 让类实现Parcelable接口。 2. 实现public void writeToParcel(Parcel out),该方法可以将当前对象的状态写入parcel. 3. 实现public void readFromParcel(Parcel in),该方法可以在parcel中读出值到对象中. 4. 向类中添加一个静态成员,名为CREATOR。该对象实现了Parcelable.Creator接口. 5. 向parcelable类中添加一个.aidl文件,以便AIDl工具可以找到。但不要向build中添加该文件。该文件的用法类似于C中的头文件.你不需要为parcelable 编译aidl文件,就像你不会编译个.h文件一样。 AIDL将使用代码中生成的这些方法和成员来伪装或解读对象。 下面的例子说明了Rect类如何实现了Parcelable协议. import android.os.Parcel; import android.os.Parcelable; public final class Rect implements Parcelable { public int left; public int top; public int right; public int bottom; public static final Parcelable.Creator CREATOR = new Parcelable.Creator { public Rect createFromParcel(Parcel in) { return new Rect(in); } public Rect[] newArray(int size) { return new Rect[size]; } }; public Rect() { } private Rect(Parcel in) { readFromParcel(in); } public void writeToParcel(Parcel out) { out.writeInt(left); out.writeInt(top); out.writeInt(right); out.writeInt(bottom); } public void readFromParcel(Parcel in) { left = in.readInt(); top = in.readInt(); right = in.readInt(); bottom = in.readInt(); } } 示例的Rect.aidl Rect类中的伪装是相当简单的。仔细看看Parcel中的其他方法,你会看到其他各种值你都可以写进Parcel. 警告:不要忽视从其他进程接收数据时的安全性考虑。在本例中,rect将从parcel中读四个数字,而你的工作则是确保这些都在可接受的值得范围内而不管调用者想要干什么。AndRoid中的安全和访问许可中有更多关于如何确保应用程序安全的信息。 调用一个IPC方法 Here are the steps a calling class should make to call your remote interface: 调用类调用远程接口的步骤: 1. 声明一个接口类型的变量,该接口类型在.aidl文件中定义。 2. 实现ServiceConnection。 3. 调用ApplicationContext.bindService(),并在ServiceConnection实现中进行传递. 4. 在ServiceConnection.onServiceConnected()实现中,你会接收一个IBinder实例(被调用的Service). 调用 YourInterfaceName.Stub.asInterfac
/
本文档为【Android帮助文档(第二部分)开发工具】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索