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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1754162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:35:25  来源:igfitidea点击:

Remote debugging with Android emulator

androidandroid-emulator

提问by zakovyrya

Is it possible to write the code/compile Android application on one machine and debug it remotely on the emulator launched on another? I'm sick and tired of the emulator constantly eating half of my laptop's CPU.

是否可以在一台机器上编写代码/编译 Android 应用程序并在另一台机器上启动的模拟器上远程调试它?我厌倦了模拟器不断吃掉我笔记本电脑一半的 CPU。

采纳答案by Christopher Orr

I haven't previously tried (or even noticed) the adb connectcommand that cmb mentioned, but I can confirm that forwarding the TCP ports yourself — such as over SSH — works fine.

我以前没有尝试过(甚至没有注意到)adb connectcmb 提到的命令,但我可以确认自己转发 TCP 端口(例如通过 SSH)工作正常。

The emulator listens on two TCP ports per instance: 5554 for the telnet interface and 5555 for control communication with tools like DDMS. So you could probably get away with only forwarding port 5555 (though I've only tried it so far with both). Each subsequent emulator takes the next available even+odd port number tuple (up to around 5580, I think).

模拟器在每个实例上侦听两个 TCP 端口:5554 用于 telnet 接口,5555 用于控制与 DDMS 等工具的通信。因此,您可能只使用转发端口 5555 就可以逃脱(尽管到目前为止我只尝试过这两个端口)。每个后续模拟器采用下一个可用的偶数+奇数端口号元组(我认为最多大约 5580)。

For reference, I did the following steps on my local machine:

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

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

I believe the emulator tries to notify a local adb server at startup; hence the need to restart adb in order for it to probe the local 5554+ ports.

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

Note that the localhostin the ssh command refers to the local interface of the remotemachine.

注意localhostssh 命令中的 指的是远程机器的本地接口。

adb devicesshowed a new emulator — emulator-5554— and I could use it as if it were running on my local machine.

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

回答by Henrik Heimbuerger

Here is how I solved it on Windows. I pretty much followed Christopher's lead, but I can't edit, so a new answer will have to do.

这是我在 Windows 上解决它的方法。我几乎跟随克里斯托弗的领导,但我无法编辑,所以必须有一个新的答案。

The problem I had was that ADB as well as the emulator was just listening on 127.0.0.1, not 0.0.0.0, for me. Otherwise I would have used TCPMon. I guess this is either different on Windows, or has changed with the latest versions of the SDK. (You can check with netstat -ban.)

我遇到的问题是 ADB 和模拟器只是在 127.0.0.1 上监听,而不是 0.0.0.0,对我来说。否则我会使用TCPMon。我想这要么在 Windows 上有所不同,要么在最新版本的 SDK 中发生了变化。(您可以使用 进行检查netstat -ban。)

  1. I installed WinSSHDon the machine that runs the emulator. (I believe it should work with freeSSHd as well, but I couldn't get a login working there.)

  2. I opened port 22 (TCP) in the Windows Firewall. (WinSSHD might be able to do that for you.)

  3. I created a virtual account in the WinSSHD GUI.

  4. I created a new PuTTY connection from the development machine to the emulator machine and made sure I could connect.

  5. Then I set up tunnelling in PuTTY: Connection -> SSH -> Tunnels

    Source port: 5554
    Destination: localhost:5554
    Type: Local/Auto

    Source port: 5555
    Destination: localhost:5555
    Type: Local/Auto

    (Connect and keep PuTTY open, to maintain the tunnel.)

  6. Now I fired up the emulator on the remote machine and made sure that ADB is not running there.

  7. I restarted ADB on the development machine (adb kill-server, then adb start-server).

  8. adb devicesand the remote emulator showed up as emulator-5554 device. I could now deploy and run my app straight from Eclipse/ADT, where the emulator showed up under Virtual Devices as if it was a local emulator.

  1. 我在运行模拟器的机器上安装了WinSSHD。(我相信它也应该与 freeSSHd 一起使用,但我无法在那里登录。)

  2. 我在 Windows 防火墙中打开了端口 22 (TCP)。(WinSSHD 或许能够为您做到这一点。)

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

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

  5. 然后我在 PuTTY 中设置隧道:Connection -> SSH -> Tunnels

    Source port: 5554
    Destination: localhost:5554
    Type: Local/Auto

    Source port: 5555
    Destination: localhost:5555
    Type: Local/Auto

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

  6. 现在我在远程机器上启动了模拟器并确保 ADB 没有在那里运行。

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

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

回答by Patrick McKinnon

I realize this question is really old, but I solved the problem slightly differently, and it took me a while to figure out this trivial solution.

我意识到这个问题真的很老,但我解决的问题略有不同,我花了一段时间才弄清楚这个微不足道的解决方案。

I usually use a Windows7 PC or laptop (depending on where I'm working) as my front-end because I like the GUI, however I prefer to do all of my edit/compile/debug on a headless Ubuntu server because of all the command-line power it provides. My goal is to make each windows system as much of a thin-client as possible without any extra services (such as sshd) or firewall holes.

我通常使用 Windows7 PC 或笔记本电脑(取决于我工作的地方)作为我的前端,因为我喜欢 GUI,但是我更喜欢在无头 Ubuntu 服务器上进行所有编辑/编译/调试,因为所有这些它提供的命令行功能。我的目标是使每个 Windows 系统尽可能成为瘦客户端,而没有任何额外的服务(例如 sshd)或防火墙漏洞。

So here is the senario:

所以这里是senario:

  • System-A: Windows7 system with android emulator running
  • System-B: Ubuntu server with SDK installed
  • System-A:运行android模拟器的Windows7系统
  • System-B:安装了 SDK 的 Ubuntu 服务器

The problem as described earlier is that the emulator on System-A binds to localhost, not the external ethernet interface, so adb on the System-B cannot access the emulator on System-A. All you need to do is set up remote port forwarding in PuTTY for your SSH connection to System-B. The trick is to check the "Remote" radio button when you create the two tunnels so that the tunnel direction is reversed (tunneling from the server you are logging into to the client you are logging in from).

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

tunnel screenshot

隧道截图

Finally, connect with adb to "localhost" on System-B after establishing the SSH connection:

最后,在建立 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

Now you can download images/debug as normal, and it is a trivial matter to switch to a different Windows system if you want to take your laptop out and get some coffee.

现在你可以正常下载图像/调试了,如果你想把你的笔记本电脑拿出来喝杯咖啡,切换到不同的 Windows 系统是一件小事。

In addition, by also tunneling port 5037 in the same manner you can actually forward your adb server connection so that you can connect a real android device over USB on System-A, and download images to it from System-B. In order for this to work, you need to make sure that the adb server is running on System-A, and not running on System-B before starting your SSH session:

此外,通过以相同的方式隧道端口 5037,您实际上可以转发您的 adb 服务器连接,以便您可以通过系统 A 上的 USB 连接真正的 android 设备,并从系统 B 下载图像。为了使其工作,在开始 SSH 会话之前,您需要确保 adb 服务器在系统 A 上运行,而不是在系统 B 上运行:

First, start the adb server on System-A (command prompt)

首先,在 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

Next, kill the adb server on System-B

接下来,杀死 System-B 上的 adb 服务器

System-B$ adb kill-server

Finally, restart your ssh session to System-B and verify

最后,重新启动与 System-B 的 ssh 会话并验证

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

回答by Shlublu

I found an easy way to do this if your two machines are in the same private network and therefore do not need to use SSH encryption (which is the common case). This may help as an SSH tunnel can be quite long and difficult to install. For example, installing an SSH daemon under Cygwin / Windows for the first time may lead to give up (well, I gave up).

如果您的两台机器在同一个专用网络中,因此不需要使用 SSH 加密(这是常见情况),我找到了一种简单的方法来执行此操作。这可能会有所帮助,因为 SSH 隧道可能很长且难以安装。比如第一次在 Cygwin/Windows 下安装 SSH 守护进程可能会导致放弃(好吧,我放弃了)。

Under Windows, what follows requires having Cygwin installed with the package httptunnel. This must work under Linux / httptunnelas well but I didn't try.

在 Windows 下,接下来需要安装 Cygwin 和httptunnel包。这也必须在 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
    
  • 在其中一台机器上运行模拟器(假设它的主机名为HostEmulator

  • 在另一台机器上启动 Eclipse(我们称之为HostEclipse

  • 在每台机器上打开一个 Cygwin 终端,然后,

  • HostEmulator 上,输入以下 cygwin 命令

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

htsmeans Http Tunnel Server.

hts表示Http Tunnel Server

These two commands create two half-bridge that listen to the ports 10001 and 10001 and that redirect the I/O of these ports to the local ports 5554 and 5555, which are the ports used by the emulator (actually, the first lauched emulator - if you are several of them running they will use higher port numbers as seen in other replies of this page).

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

  • On HostEclipse, enter these ones:

    htc -F 5554 HostEmulator:10000
    htc -F 5555 HostEmulator:10001
    
  • HostEclipse 上,输入这些

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

htcmeans Http Tunnel Client.

htc表示Http Tunnel Client

These commands create the missing half-bridges. They listen to the local ports 5554 and 5555 and redirects the I/O of these ports to the half-bridges we have created on HostEmulatorjust before.

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

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

    adb kill-server
    adb start-server
    adb devices
    
  • 然后,仍然在HostEclipse 上,输入以下三个命令

    adb kill-server
    adb start-server
    adb devices
    

This restarts adb as it doesn't detect the remote emulator otherwise. It must be doing some scanning at startup. And then it lists the devices (the available emulators) just for checking.

这将重新启动 adb,否则它不会检测到远程模拟器。它必须在启动时进行一些扫描。然后它列出了仅用于检查的设备(可用的模拟器)。

  • And there you go.
  • 你去吧。

You can work with your remote emulator as if it was local. You have to keep the Cygwin terminals open on both machine otherwise you would kill the half bridges you created.

您可以像在本地一样使用远程模拟器。你必须在两台机器上保持 Cygwin 终端打开,否则你会杀死你创建的半桥。

I used the port 10000 and 10001 for the machine/machine exchanges here, but of course you can use other ports as long as they are not already in use.

我在这里使用端口 10000 和 10001 进行机器/机器交换,但是当然您可以使用其他端口,只要它们尚未被使用即可。

回答by Emirikol

My solution for windows + AndroVM (which requires a host-only adapter) when my ssh service failed to start. so it doesn't require any additional software.

当我的 ssh 服务无法启动时,我的 windows + AndroVM(需要一个仅主机适配器)的解决方案。所以它不需要任何额外的软件。

adb connect <Andro VM IP>
adp tcpip 555

On cmd prompt run as admin:

在 cmd 提示符下以管理员身份运行:

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

open TCP port 5555 in windows firewall.

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

Then, from the second PC run:

然后,从第二台 PC 运行:

adb connect <host ip>

回答by Sarpe

None of the proposed solutions worked for me. I've started from Emirikol's solution and refined it, as with the new Android API > 21 the emulator was appearing offline and I had to go to Genymotion settings and leave Android SDK path empty. And from command line:

没有提出的解决方案对我有用。我从 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>

source:http://www.sarpex.co.uk/index.php/2016/10/02/connect-genymotion-emulator-remotely/Disclaimer, I'm the author.

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

回答by android.weasel

When you run adb, it starts a server copy of itself if one isn't already running. You can start that copy yourself on the machine with the device and since sdk 4.3 you can give it the -a option to tell that server to listen for remote machines. Do that with the following command which doesn't exit:

当您运行 adb 时,它会启动自己的服务器副本(如果尚未运行)。您可以在带有设备的机器上自己启动该副本,并且从 sdk 4.3 开始,您可以为其提供 -a 选项以告诉该服务器侦听远程机器。使用以下不退出的命令执行此操作:

adb -a -P 5037 server nodaemon

adb -a -P 5037 服务器节点

On the machine you want to use the device from, set ADB_SERVER_SOCKET to tcp:xxxx:5037 in an environment variable (or give the same value to each adb invocation with the -L option), where xxxx is the IP address or hostname of the machine with the devices, and 5037 matches the port you gave the in the command above.

在要使用设备的机器上,在环境变量中将 ADB_SERVER_SOCKET 设置为 tcp:xxxx:5037(或使用 -L 选项为每个 adb 调用赋予相同的值),其中 xxxx 是 IP 地址或主机名机器与设备,并且 5037 匹配您在上面的命令中提供的端口。

We use this to give access to about 100 emulators spread over 3 machines to a machine running end to end tests in parallel, and to developers wanting to share real devices remotely.

我们使用它来访问分布在 3 台机器上的大约 100 个模拟器到并行运行端到端测试的机器,以及希望远程共享真实设备的开发人员。

You can forward ports to and from the emulator with adb forward and adb reverse, and they'll appear on the machine with the devices (not the machine you're running 'adb forward' from).

您可以使用 adb forward 和 adb reverse 将端口转发到模拟器或从模拟器转发端口,它们将出现在带有设备的机器上(而不是您运行“adb forward”的机器)。

回答by Chris Boyle

I don't have a second machine with the SDK to hand, but I note that the emulator's listen ports (default 5554, 5555) are listening on 0.0.0.0, i.e. reachable from remote machines, and that adb --helpshows a connect <host>:<port>command. I assume that would make it show up in adb devicesso adbcommands work on it. For Eclipse, try "Run / Run Configurations..." and set the Target to Manual. That gives you a "device chooser" which I'm guessing would include a remote emulator if adb is connected to it. Worth a try.

我手头没有带有 SDK 的第二台机器,但我注意到模拟器的监听端口(默认 5554、5555)正在监听0.0.0.0,即可以从远程机器访问,并且adb --help显示了一个connect <host>:<port>命令。我认为这将使它在出现adb devices这样adb的命令就可以了工作。对于 Eclipse,尝试“运行/运行配置...”并将目标设置为手动。这为您提供了一个“设备选择器”,如果 adb 连接到它,我猜它会包括一个远程模拟器。值得一试。