检测安卓模拟器何时完全启动

40

我想编写一个脚本,在启动模拟器后,系统完全启动之后,安装一个apk文件。

如何知道模拟器何时完全启动,以便运行安装命令?在这里http://developer.android.com/guide/developing/tools/adb.html中说明adb wait-for-device install <app>.apk是不正确的。

那么我该如何实现呢?这可能吗?我的唯一选择是等待几分钟,直到我可以确认模拟器已经启动了吗?


1
请尝试此处提到的解决方案:https://dev59.com/41DTa4cB1Zd3GeqPHC4s#3618198 - ankitjaininfo
https://dev59.com/E2rWa4cB1Zd3GeqP7R1r#13095523 - Alex P.
7个回答

47

adb shell getprop init.svc.bootanim

这会告诉你启动动画是否正在运行。我们在无头构建服务器上使用它来检查仿真器是否已启动。dac2009 的 sys.boot_completed 让我发现了该标志。我们使用 init.svc.bootanim 而不是 boot_completed,因为 boot_completed 往往会触发得太早。


1
如何将无头模拟器加载到内存中? - Dharmesh
1
当我在测试@neuron的回答时,我意识到我必须检查一个不同的属性以实现最可靠的验证_dev.bootcomplete_(请注意前缀:dev而不是sys,因为sys.boot_completed在初始化完成之前会变成1)。 - David Santiago Turiño
我发现dev.bootcomplete也不太可靠,我仍然更喜欢init.svc.bootanim - Prof. Moriarty
2
注意:如果启用了“-no-boot-anim”标志,则此方法无效。 - Mark Han

25
while [ "`adb shell getprop sys.boot_completed | tr -d '\r' `" != "1" ] ; do sleep 1; done

这段代码从sys.boot_completed获取信息,如果系统启动已经完成,它会去掉换行符并将结果值与1进行比较。如果不等于1/未完全启动,则会休眠1秒后再次尝试。

只需在此代码行之后放置您的adb install ...。


当我检查一个模拟器时,这对我有效。但如果我想要检查多个模拟器,则会出现“超过一个模拟器”的错误。如何解决? - Tarek Salah uddin Mahmud
在这种情况下,您需要指定要使用adb的设备。使用adb -s DEVICE_IDENTIFIER而不是adb shell。DEVICE_IDENTIFIER是在调用adb devices时看到的ID。如果您想等待所有模拟器都启动。 - Sebo
那个尾随的换行符让我一直在打转。谢谢! - Big McLargeHuge
1
一个更简单的方法是避免解析,而是在目标上执行检查和休眠。adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done;' - Lucas

14

我不确定这是否适用于所有设备,但是经过我测试的设备可以使用。

如果您进入shell,可以输入getprop命令,以获取手机属性列表。应该会有一个名为“sys.boot_completed”的属性。

如果您键入“getprop sys.boot_completed”,则会响应“1”,表示系统已启动,如果系统未启动,则为空字符串。


我在现场遇到至少一个设备没有设置该属性,但如果它存在并且已设置,则您知道您的设备已启动。您还可以查找dev.bootcomplete,但我也遇到过一个在现场没有设置它的设备。 - Edward Falk
我将 sys.boot_completedinit.svc.bootanim 进行了测试,发现 sys.boot_completed 是两种方法中更为保守的。如果您的模拟器有检查 sys.boot_completed 的选项,请使用它! - Gi0rgi0s

7

只需使用-delay-adb标志运行模拟器,然后运行adb wait-for-device命令。当模拟器启动后,adb命令将退出。


这个尚未被添加到文档中,但在这里提到:https://androidstudio.googleblog.com/2019/05/emulator-2907-canary.html。然而,在我的测试中它无限挂起。 - Big McLargeHuge

1
使用来自service.bootanim.exit的引导状态可能会产生不稳定的结果,如果您尝试安装应用程序,则会出现此情况。
特别是如果您在使用adb shell su 0 setprop ctl.restart zygote重新启动后进行检查。 service.bootanim.exit是模拟器启动时显示在白色背景上的“Google”图标。当它完成后,下一个状态是“正在启动手机”屏幕,在这个屏幕上不可能立即安装应用程序。
我发现在UI完成渲染后从无网络切换到LTE或WIFI发生的情况。这样,模拟器已准备好接受用户输入,包括加载应用程序。
adb shell dumpsys connectivity | sed -e '/[0-9] NetworkAgentInfo.*CONNECTED/p' -n 

UI加载完成后,模拟器网络状态会从无网络变为LTE,最终变为WIFI。在支持Google API的Android 10上进行了测试。

如果没有使用sed,你会得到过载的信息。如果想要找到/未找到响应,请尝试使用grep查找WIFI或LTE。


0

如果您使用“-logcat VERBOSE”启动模拟器并等待指示模拟器已启动的消息,则可以解析模拟器的stdout输出。

我目前在输出中没有看到任何好的消息,但是您可以编写一个应用程序来监听“android.intend.action.BOOT_COMPLETED”并将某些内容写入日志。

有关更多信息,请参见http://developer.android.com/guide/developing/tools/emulator.html


-2
您可以设置一个广播接收器,该接收器可以通知设备启动已完成。
android:name="android.intent.action.BOOT_COMPLETED"

2
这不是我要问的。我说的是在我的家用电脑上编写一个脚本,以安装应用程序到模拟器中,从而能够自动化测试过程。 - Catalin Morosan
糟糕!..你的标题写着“检测Android模拟器何时完全启动”,而我认为这可能是最好的方法。无论如何,即使你想从系统运行脚本,你也需要知道模拟器何时启动完成。也许你可以从广播开始某种服务,该服务可以调用本地IIS中的URL来触发你的脚本... - DeRagan

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