问题: Could not connect to development server(Android)
翻译后内容为:
连接不到开发的服务器。
请按照以下的步骤来修复此问题:
确保包服务器在运行
确保你的设备或者模拟器连接着电脑,并且手机打开了USB调试模式,然后在cmd中运行adb devices来查看已经连接好的设备列表
确保飞行模式是关闭的
如果是使用真机来开发,输入 adb reverse tcp:8081 tcp:8081来检查设备
如果设备与开发机在相同网络, 则输入 开发机IP:8081
调试前环境
- 已经在代码目录运行
yarn start
(即npx react-native start
)启动了代码服务器. - 已经运行
yarn android
(即npx react-native run-android
)编译了java代码并安装调试apk到模拟器.
解决步骤:
-
检查包服务器是否运行正常
在本地开发机上访问 http://localhost:8081/index.bundle?platform=android&dev=true&minify=false, 能够访问, 得到正确内容. 确认没有问题. -
判断模拟器或手机能否访问相应地址
在模拟器的browser上打开http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false,发现不能访问.
网上查了资料, 有的人说先运行adb reverse tcp:8081 tcp:8081
, 前面的tcp:8081
表示模拟器或手机上的端口, 后面的tcp:8081
表示开发机上的服务端口, 打开模拟器浏览器尝试访问<10.0.2.2:8081>失败, 尝试在android模拟器的浏览器上将<10.0.2.2:8081>替换为localhost:8081或<127.0.0.1:8081>, 访问成功. 判断出结论是模拟器不能访问<10.0.2.2:8081>.
注: 我一直没明白, 为啥在模拟器上要访问10.0.2.2
, 上网查找资料得知10.0.2.2
代表的是模拟器所在宿主机(即开发机)的ip地址.10.0.2.15
是模拟器的以太网接口. 关于模拟器网络地址空间
这部分可以参考https://developer.android.com/studio/run/emulator-networking?hl=zh-cn.
尝试访问http://10.0.2.15:8081/index.bundle?platform=android&dev=true&minify=false也没有成功.
根据这一步的分析,10.0.2.2
不能访问是导致出现红屏的原因, 但在linux的android下又无法唤起dev menu
, 导致无法修改10.0.2.2
为localhost
或127.0.0.1
.
为什么不能访问10.0.2.2
和10.0.2.15
? 用adb shell
进入模拟器,su root
后执行ping 10.0.2.2
却能ping通. 为什么不能访问网页呢?
偶尔一次直接在命令行运行emulator -avd 5.4_FWVGA_API_29 -writable-system -no-snapshot-load
, 未做任何网络方面设置, 却发现能访问10.0.2.2
, 怪了!(注意:此处可以运行emulator -list-avds
获取当前avd列表) -
继续寻找android-studio启动emulator无法连接
10.0.2.2:8081
的原因
分析android-studio启动的emulator最终所用的命令行/home/windsome/Android/Sdk/emulator/qemu/linux-x86_64/qemu-system-x86_64 -netdelay none -netspeed full -studio-params /home/windsome/temp/emu1.tmp -avd 5.4_FWVGA_API_29
, 找到/home/windsome/temp/emu.tmp
文件, 内容为
http.proxyHost=127.0.0.1
http.proxyPort=43349
https.proxyHost=127.0.0.1
https.proxyPort=43349
难道这是导致不能访问的原因?
再次使用命令行启动模拟器, 命令行为: /home/windsome/Android/Sdk/emulator/qemu/linux-x86_64/qemu-system-x86_64 -avd 5.4_FWVGA_API_29 -writable-system -no-snapshot-load
, (注意,有时重启机器后不能正常运行emulator, 一直停着, 可能是/dev/kvm
的权限不对, 修正方案为见后面问题: /dev/kvm没有权限
).
比较两个不同运行方式的命令行, 差别注意在于adt中启动多了-studio-params /home/windsome/temp/emu1.tmp
, 这个文件有时并不存在, 很奇怪. 根据之前存在的那个emu.tmp
文件估计是adt中设置了代理导致模拟器启动后会自动使用这些代理, 从而导致网络请求走了代理, 无法回到正确的地址.
为了验证这个猜测, 在adt中打开设置页,搜索proxy
,设置为无代理,再次从adt
中启动模拟器,再次在浏览器中访问10.0.2.2:8081
,能够正确访问,且无需做adb reverse
,至此,基本判断出来,是代理导致的.
- 新问题又产生了,代理怎么影响了
10.0.2.2
的访问?是否可以在adt保持proxy
的情况下,做其他修改,使得模拟器仍然正常?
运行emulator --help | grep studio
, 得到-studio-params <file> used by Android Studio to provide parameters
, 得知-studio-params
是adt提供的参数. 如何找到系统代理相关内容呢? 目前没查到相关资料, 只能以后有时间再分析了.
其余派生问题
/dev/kvm
没有权限
ProbeKVM: This user doesn't have permissions to use KVM (/dev/kvm).
The KVM line in /etc/group is: [LINE_NOT_FOUND]
If the current user has KVM permissions,
the KVM line in /etc/group should end with ":" followed by your username.
If we see LINE_NOT_FOUND, the kvm group may need to be created along with permissions:
sudo groupadd -r kvm
# Then ensure /lib/udev/rules.d/50-udev-default.rules contains something like:
# KERNEL=="kvm", GROUP="kvm", MODE="0660"
# and then run:
sudo gpasswd -a $USER kvm
If we see kvm:... but no username at the end, running the following command may allow KVM access:
sudo gpasswd -a $USER kvm
You may need to log out and back in for changes to take effect.
ERROR | x86 emulation currently requires hardware acceleration!
CPU acceleration status: This user doesn't have permissions to use KVM (/dev/kvm).
The KVM line in /etc/group is: [LINE_NOT_FOUND]
If the current user has KVM permissions,
the KVM line in /etc/group should end with ":" followed by your username.
If we see LINE_NOT_FOUND, the kv
More info on configuring VM acceleration on Linux:
https://developer.android.com/studio/run/emulator-acceleration#vm-linux
General information on acceleration: https://developer.android.com/studio/run/emulator-acceleration.
上面是日志输出的解决方案, 分为两种情况, /etc/group
是否存在kvm
组, 若存在, 则只需要运行sudo gpasswd -a $USER kvm
将当前用户加入到kvm
组. 若不存在, 则需要执行sudo groupadd -r kvm
创建组, 并将当前用户加入到组sudo gpasswd -a $USER kvm
, 且还需确认/lib/udev/rules.d/50-udev-default.rules
中存在包含KERNEL=="kvm", GROUP="kvm", MODE="0660"
内容的行, 注意, 有时这一行被#
注释了, 需要打开.