使用 Android 模拟器进行远程调试

110
有没有可能在一台机器上编写/编译Android应用程序,并在另一台启动模拟器上进行远程调试?我已经受够了模拟器总是占用我的电脑CPU的一半。
11个回答

81

我之前没有尝试过(甚至没有注意到)cmb提到的adb connect命令,但我可以确认自己转发TCP端口 - 比如通过SSH - 是可行的。

模拟器每个实例监听两个TCP端口:5554用于telnet接口,5555用于与DDMS等工具进行控制通信。因此,您可能只需要转发端口5555(虽然我只尝试过使用两个端口)。随后的每个模拟器都采用下一个可用的偶数+奇数端口号元组(最多到5580左右)。

作为参考,在我的本地机器上执行了以下步骤:

  • ssh -NL 5554:localhost:5554 -L 5555:localhost:5555 myuser@remote-server
  • killall adb; adb devices

我相信模拟器在启动时会尝试通知本地的adb服务器;因此需要重新启动adb以便它能够探测本地的5554+端口。

请注意,ssh命令中的localhost指的是远程机器的本地接口。

adb devices显示了一个新的模拟器 - emulator-5554 - 我可以像在本地机器上运行一样使用它。


2
非常好用,即使在我的Windows 7机器上使用Putty SSH端口转发也没有问题。谢谢。 - gsbabil
1
@JimMcKeeth:根据上面的网络配置,打开Putty,进入Connection > SSH > Tunnels。现在添加一个条目,源端口:5556,目标:localhost:5554。重复相同的步骤,源端口:5557,目标:localhost:5555。干杯! - gsbabil
6
请记得在服务器上执行 killall adb 命令,因为模拟器无法接受多个连接,否则本地机器将无法与其建立连接。这会导致模拟器处于“离线”状态。 - Henrique de Sousa
调试对我不起作用,在模拟器上的设备上,它说正在等待调试器连接,但是我的本地机器上的Android Studio拒绝连接调试器,显示“等待应用程序在线。无法连接到远程进程。中止调试会话。” - RikuPotato
你能否看一下我的问题:https://stackoverflow.com/q/75002348/5105442 - Sepehr Estaki

23

我知道这个问题已经很老了,但是我以稍微不同的方式解决了这个问题,并花了一些时间才找到这个微不足道的解决方案。

通常我会使用Windows7电脑或笔记本电脑(根据我的工作地点)作为我的前端,因为我喜欢图形用户界面(GUI),但是我更喜欢在无头Ubuntu服务器上进行所有编辑/编译/调试,因为它提供了命令行强大的功能。我的目标是尽可能将每个Windows系统作为纯客户机而没有任何额外的服务(例如sshd)或防火墙漏洞。

所以这里是场景:

  • System-A:运行Android模拟器的Windows7系统
  • System-B:安装了SDK的Ubuntu服务器

正如之前描述的那样,问题在于System-A上的模拟器绑定到了localhost而不是外部以太网接口,因此System-B上的adb无法访问System-A上的模拟器。你需要做的就是在PuTTY中为与System-B的SSH连接设置远程端口转发。诀窍是在创建两个隧道时选中"Remote"单选按钮,以便隧道方向被反转(从您登录的服务器隧道到你从中登录的客户端)。

隧道截图

最后,在建立SSH连接后,使用adb连接到System-B上的"localhost"。

System-B$ adb connect localhost
connected to localhost:5555
System-B$ adb devices
List of devices attached
localhost:5555  device
现在你可以像往常一样下载图像/调试,如果你想把电脑拿出去喝咖啡,切换到另一个Windows系统也是微不足道的事情。

此外,通过以相同的方式隧道传输端口5037,您实际上可以转发adb服务器连接,这样您就可以在System-A上通过USB连接真正的Android设备,并从System-B向其下载图像。为了使此功能正常工作,您需要确保adb服务器在启动SSH会话之前在System-A上运行,并且在System-B上没有运行:

首先,在System-A上启动adb服务器(命令提示符)

C:\> adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
C:\> adb devices
List of devices attached
3435F6E6035B00EC        device

接下来,在System-B上关闭adb服务器。

System-B$ adb kill-server

最后,重新开始您与 System-B 的 ssh 会话并进行验证。

System-B$ adb devices
List of devices attached
3435F6E6035B00EC        device

有没有办法在 System-A 上不安装 Android SDK(即 Windows 机器)的情况下完成这个操作? - Keith Twombley
不行,因为adb服务器和USB驱动程序需要在System-A上运行才能与设备通信。 - Patrick McKinnon
我也用类似的设置完成了这个操作: Windows 7(运行模拟器)-> Linux(由于网络原因需要跳转...)-> 运行Eclipse的OS X。我能够通过“adb devices”看到设备并从Eclipse中使用模拟器。问题在于它无法识别模拟器的Android目标,因此我必须手动选择每次运行的目标。 - Frank
如果你需要在Mac OS X上使用Putty,你可以在这里找到它:http://www.mac-tools.org/putty-fur-mac-os-x/02/2012/ 对我来说,使用这个工具很有效。 - Bruno Bieri
@PatrickMcKinnon,这个东西在 System-A 上运行得很好,但是在 System-B 上调用“adb devices”时出现了未授权的情况。在 System-B 上,“adb devices”显示它正常工作。有什么帮助吗? - Tejas Sherdiwala
显示剩余2条评论

21
这是我在Windows上解决它的方法。 我基本上遵循了Christopher的建议,但我无法进行编辑,所以必须新建一个答案。
我的问题是ADB和模拟器只是在127.0.0.1上监听,而不是0.0.0.0。否则我会使用TCPMon。我猜这在Windows上可能有所不同,或者随着SDK的最新版本而改变。(您可以使用netstat -ban进行检查。)
  1. 我在运行模拟器的机器上安装了WinSSHD。(我认为它也可以与freeSSHd一起使用,但我无法在那里获得登录权限。)

  2. 我在Windows防火墙中打开了端口22(TCP)。 (WinSSHD可能可以为您完成此操作。)

  3. 我在WinSSHD GUI中创建了一个虚拟账户。

  4. 我从开发机器到模拟器机器创建了一个新的PuTTY连接,并确保我可以连接。

  5. 然后我在PuTTY中设置了隧道:连接 -> SSH -> 隧道

    源端口:5554
    目标:localhost:5554
    类型:本地/自动

    源端口:5555
    目标:localhost:5555
    类型:本地/自动

    (连接并保持PuTTY处于打开状态,以维护隧道。)

  6. 现在我在远程机器上启动了模拟器,并确保ADB未在该机器上运行。

  7. 我在开发机器上重新启动了ADB (adb kill-server,然后 adb start-server)。

  8. adb devices,远程模拟器显示为emulator-5554 device。现在我可以直接从Eclipse/ADT部署和运行我的应用程序,在虚拟设备下模拟器显示为本地模拟器。


1
不错,但我想澄清一下:在第4步之后,您必须关闭putty,然后在第5步中再次打开它,配置隧道并重新连接。步骤6-8:首先启动模拟器,然后启动adb(在主机上)。第9步:您可能需要在客户端机器上重新启动adb,并键入adb设备以确保它正常工作。常规的DDMS和eclipse工具也应该可以使用。 - Mister Smith
@MisterSmith 很有见地,为什么不提交一份编辑?:) - Henrik Heimbuerger
@MisterSmith,您能否编辑您的答案以反映这个评论,这对问题的成功非常重要。另外,谢谢,我现在能够从我的客户机连接到我的主机了。 - Steven Combs
你们能否请看一下我的问题?:https://stackoverflow.com/q/60883810/5105442 - Sepehr Estaki

6
如果你的两台机器在同一私有网络中,因此不需要使用SSH加密(这是常见情况),那么我发现有一种简单的方法来实现这个目标。这可能会帮助你,因为SSH隧道可能会很长而且安装起来很困难。例如,在Cygwin / Windows下第一次安装SSH守护程序可能会导致放弃(好吧,我放弃了)。
在Windows下,以下步骤需要使用已安装httptunnel软件包的Cygwin。这也应该适用于Linux / httptunnel ,但我没有尝试过。
  • Run the emulator on one of the machines (let's say its host name is HostEmulator)

  • Start Eclipse on the other machine (let's call it HostEclipse)

  • Open a Cygwin terminal on each machine, and then,

  • On HostEmulator, enter the following cygwin commands:

    hts -F localhost:5554 10000
    hts -F localhost:5555 10001
    

hts指的是Http隧道服务器。

这两个命令创建了两个半桥,它们监听端口10001和10001,并将这些端口的I/O重定向到本地端口5554和5555,这些端口是模拟器使用的端口(实际上是第一个启动的模拟器 - 如果有多个运行,则会使用更高的端口号,如本页其他回复中所示)。

  • On HostEclipse, enter these ones:

    htc -F 5554 HostEmulator:10000
    htc -F 5555 HostEmulator:10001
    

htc指的是Http隧道客户端

这些命令创建了缺失的半桥。它们监听本地端口5554和5555,并将这些端口的I/O重定向到我们刚刚在HostEmulator上创建的半桥。

  • Then, still on HostEclipse, enter these three commands:

    adb kill-server
    adb start-server
    adb devices
    

如果不重启adb,它将无法检测到远程模拟器。它必须在启动时进行一些扫描。然后列出设备(可用的模拟器)只是为了检查。

  • 就是这样。

你可以像本地一样使用远程模拟器。 你必须在两台机器上都保持Cygwin终端打开,否则会导致创建的桥接失败。

我在这里使用10000和10001端口进行机器之间的交换,但是你当然可以使用其他端口,只要它们没有被占用。


4
当你运行adb时,如果没有正在运行的服务器副本,它会启动一个。您可以在具有设备的计算机上自行启动该副本,并自sdk 4.3以来,可以使用-a选项告诉该服务器监听远程计算机。使用以下命令执行此操作,该命令不会退出:
adb -a -P 5037 server nodaemon
在要使用设备的计算机上,在环境变量中将ADB_SERVER_SOCKET设置为tcp:xxxx:5037(或使用-L选项为每个adb调用提供相同的值),其中xxxx是具有设备的计算机的IP地址或主机名,而5037与上面命令中给出的端口匹配。
我们使用此方法将约100个模拟器分布在3台计算机上,以便在并行运行端到端测试的计算机和希望远程共享真实设备的开发人员都可以访问。
您可以使用adb forward和adb reverse将端口转发到和从模拟器上,并且它们将显示在具有设备的计算机上(而不是您从中运行'adb forward'的计算机)。

你能提供更多关于这个解决方案的细节吗?我按照你说的做了一切,但在Android Studio中的“选择部署目标”中没有任何设备。我在第二台电脑上使用Genymotion。 - konstantin_doncov
@don-prog,你没有说过这个命令行是否适用于你:adb -L tcp:remotehost:1234 devices。如果它可以使用,那么你需要找出Android Studio是否支持远程ADB,我不会感到惊讶,如果它坚持使用本地设备。 - android.weasel

3
没有一个提出的解决方案适用于我。 我从Emirikol的解决方案开始,并进行了改进,因为新的Android API> 21会导致模拟器脱机,并且我必须进入Genymotion设置并将Android SDK路径留空。 然后从命令行输入:
netsh interface portproxy add v4tov4 listenport=5555 connectport=5555 connectaddress=<emulatorIP>

netsh interface portproxy add v4tov4 listenport=5554 connectport=5554 connectaddress=<emulatorIP>

来源:http://www.sarpex.co.uk/index.php/2016/10/02/connect-genymotion-emulator-remotely/ 免责声明,我是作者。

完美的答案和文章!如果你使用Genymotion,那就使用这个解决方案。这篇文章是关于Windows和Mac的,但我有本地的Ubuntu和远程的Ubuntu,一切都很好。挽救了我的一周! - konstantin_doncov

2

当我的ssh服务无法启动时,我为Windows + AndroVM(需要一个host-only适配器)提供了解决方案。因此,它不需要任何额外的软件。

adb connect <Andro VM IP>
adp tcpip 555

在管理员权限下的 CMD 提示符上运行:

netsh interface portproxy add v4tov4 listenport=5555 listenaddress=<host ip> connectport=5555 connectaddress=<Andro VM IP>

在Windows防火墙中打开TCP端口5555。

然后,在第二台电脑上运行:

adb connect <host ip>

1
这篇文章包含了很多答案,但缺少逐步说明。
因此,本回答将解释如何连接两台计算机,以在一台计算机的模拟器上运行另一台计算机的项目。
进一步操作前需要满足以下要求:
  1. 防火墙应关闭。
  2. 两台电脑必须连接在同一个网络中。

注:

  • 运行Android Studio的计算机称为“PC_AS”
  • 运行模拟器的计算机称为“PC_EM”

第一步:

在运行Android Studio的计算机上,打开终端窗口并运行以下命令。

ssh -NL 5554:localhost:5554 -L 5555:localhost:5555 dhaval@192.168.0.104
  • 以上命令将PC_AS的55545555端口转发到PC_EM上的相同端口。因此,在PC_EM上运行的模拟器可以在PC_AS上被检测到。
  • dhaval@192.168.0.104是PC_EM的地址。地址格式为用户名@本地IP地址

一旦您运行了上述命令,如果命令成功执行,终端窗口将不会显示任何内容。看起来好像什么也没有发生,但是该过程正在那里运行。

| 注意:在您想停止远程调试之前,请勿关闭此终端。


步骤2:

现在在PC_AS上打开另一个终端窗口,并依次运行以下命令。

  1. killall adb;adb devices 此命令将停止adb并停止服务器。
  2. adb start-server 此命令将启动adb服务器。
  3. adb devices 此命令将列出所有已连接的adb设备。

一旦您运行了上述命令,您将看到PC_EM的模拟器现在在PC_AS上被检测到。现在,您可以在这些模拟器上运行项目并进行远程调试。

| 注意:在执行上述过程时,模拟器可能会显示一个对话框来信任传入的请求。


0

Android模拟器默认监听本地端口5555,因此连接到远程模拟器的一种方法是使用端口转发工具将所有局域网数据包转发到本地5555端口。

其中一个优秀的工具是Trivial Port Forward

以下是命令:

trivial_portforward.exe 1234 127.0.0.1 5555

这里的1234是开发计算机将连接的端口号。127.0.0.1是环回地址,5555是模拟器的端口。

有关更详细的示例,请参阅我的博客文章


0

这是我如何从主机macOS通过模拟器使其工作到macOS客户端的方法。

A:一行命令

在模拟器的主机上

 socat tcp-l:5560 tcp:localhost:5559

在客户端

 adb connect <IP>:5560

带隧道

在带有模拟器的主机上

host$ adb kill-server
host$ adb -a nodaemon server

在使用Android Studio的客户端上

client$ adb kill-server
client$ ssh -L 5037:localhost:5037 <host-IP>

在 Android Studio 上为客户端打开第二个 shell

client$ adb kill-server  # I observe first it kills client adb
client$ adb kill-server  # then it kills server adb, do it maybe once more
client$ adb devices      # show devices on server now

现在我也在Android Studio中看到了主机模拟器

enter image description here


第二个解决方案尝试了几次后成功了。如果我无法预览模拟器屏幕,该怎么办?Scrcpy返回“Device: unknown Android SDK built for x86_64 (Android 12)”。 - deadfish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接