解决Hyper-V占用端口导致 Android Studio 模拟器无法启动的问题

838 阅读6分钟

问题:AVD偶尔无法启动

    Android studio 创建的 AVD 无法启动,点击启动按钮弹窗提示模拟器终止之类的提示框:xxxx terminal,没有其他错误提示了。而且这种情况是不是必现,重启电脑后有时候无法启动,有时候又可以启动。

直接解决问题

  1. 方法一:重启 winnat 服务先执行net stop winnat 再执行 net start winnat
net stop winnat
net start winnat
  1. 方法二:手动指定协议 tcp 动态端口范围(推荐)netsh int ipv6 set dynamic tcp start=40001 num=14000
netsh int ipv6 set dynamic tcp start=40001 num=14000

(以下的只是些过程和细节)

排查问题

   由于无法启动的提示框没有过多的可用信息,所以只能搜索AVD 无法启动等,但是结果都不能解决问题。于是乎想到命令行的方式启动AVD看看是否有更多的错误信息,果然,多用命令行还是有帮助的。

  1. 进入Android SDK Location(SDK 安装目录),再进入 emulator文件夹,在此文件夹打开命令行。执行:.\emulator.exe -list-avds 查看已有的模拟器。结果:
PS D:\Dev\Android\Sdk\emulator> .\emulator.exe -list-avds
INFO    | Storing crashdata in: C:\Users\ADMINI~1\AppData\Local\Temp\\AndroidEmulator\emu-crash-34.2.16.db, detection is enabled for process: 25532
Pixel_2_XL_API_34

Pixel_2_XL_API_34 是创建的模拟器

  1. 用命令行启动模拟器 执行.\emulator.exe -avd Pixel_2_XL_API_34 ,从输出的结果找到想要的信息,一般为ERROR:
WHPX on Windows 10.0.19045 detected.
Windows Hypervisor Platform accelerator is operational
ERROR   | It seems too many emulator instances are running on this machine. Aborting.
WARNING | QEMU main loop exits abnormally with code 1

重点是ERROR | It seems too many emulator instances are running on this machine. Aborting. 大概意思是:已经有其他模拟器实例在运行了。可以根据信息去分析或者百度了。

  1. 排查端口是否被占用 经过一番搜索,端口被占用的可能性更大,因为我的电脑确实遇到过不少端口被占导致一些应用无法使用的情况,比如之前Neat Download Manager(NDM)的10007端口被占用导致无法下载。就算想用命令 netstat -aon|findstr "端口号" 也不知道要搜那些端口号。比如 NDM 的10007,搜不出来,但是就是被占用了。物理机没搜到,会不会是虚拟机的问题?于是找到了这篇文章:hyper-v占用其他软件或服务端口解决方案_hyper-v 端口-CSDN博客

解决问题,重启模拟器

    按照文章的说法:

  1. 使用命令 netsh int ipv4 show dynamicport tcp 可以查看目前「TCP 动态端口」的范围
netsh int ipv4 show dynamicport tcp
协议 tcp 动态端口范围
---------------------------------
启动端口        : 1024
端口数          : 13977
  1. 使用 netsh int ipv4 show excludedportrange protocol=tcp 命令查看当前所有已经被征用了的端口
netsh int ipv4 show excludedportrange protocol=tcp

协议 tcp 端口排除范围

开始端口    结束端口
----------    --------
      1062        1161
      1162        1261
      1262        1361
      1362        1461
      1462        1561
      1562        1661
      1662        1761
      1762        1861
      1862        1961
      1962        2061
      2062        2161
      2280        2379
      2380        2479
      2480        2579
      2580        2679
      2680        2779
      2780        2879
      2880        2979
      2980        3079
      3080        3179
      3180        3279
      3307        3406
      3714        3813
      3814        3913
      3914        4013
      4014        4113
      4114        4213
      4214        4313
      4314        4413
      4414        4513
      4514        4613
      4614        4713
      4714        4813
      5124        5223
      5224        5323
      5357        5357
      5358        5457
      5458        5557
      5558        5657
      5658        5757
      5758        5857
      5940        6039
      6040        6139
      6140        6239
      6240        6339
      6780        6879
      6880        6979
      6980        7079
      7080        7179
      7180        7279
      7280        7379
      7380        7479
      7480        7579
      7580        7679
      7680        7779
      7780        7879
      7905        8004
      8005        8104
      8105        8204
      8205        8304
      8305        8404
      8405        8504
      8505        8604
      8605        8704
      8705        8804
      8805        8904
      8905        9004
      9080        9179
      9180        9279
      9280        9379
      9380        9479
      9480        9579
      9620        9719
     11333       11432
     11433       11532
     11533       11632
     11633       11732
     11733       11832
     11833       11932
     11933       12032
     12033       12132
     12133       12232
     12233       12332
     12333       12432
     12433       12532
     50000       50059     *

* - 管理的端口排除。

  1. winnat 服务临时解决 先执行net stop winnat 再执行 net start winnat,这样端口可能就不会被占用了,如果还是被占用就多试几次,因为端口的使用是随机的。
net stop winnat
net start winnat
  1. 手动指定协议 tcp 动态端口范围(端口不超过65535)
netsh int ipv6 set dynamic tcp start=启动端口 num=端口数

我的设置如下:

netsh int ipv6 set dynamic tcp start=40001 num=14000

设置完后查看设置结果:netsh int ipv4 show dynamicport tcp

协议 tcp 动态端口范围
---------------------------------
启动端口        : 40001
端口数          : 14000
  1. 重启下电脑

(完)