# 虚拟屏幕

虚拟屏幕是指在您的手机上创建一个或多个虚拟的显示器，相当于一个隔离运行的后台屏幕，在后台屏幕上运行的 APP 和自动化脚本不会影响到设备主屏幕，也就是说，
在使用自动化脚本在后台屏幕上自动操作微信回复消息的同时，你可以正常使用设备屏幕刷抖音视频。我们的 WebUI 也支持了多屏幕的展示，您可以在远程桌面选择操作或查看其他屏幕。

## 创建虚拟屏幕

使用也很简单，您可以通过如下调用来创建一个虚拟屏幕，这将为您创建一个和当前屏幕一样分辨率以及 DPI 的虚拟屏幕。

```python
vd = d.create_virtual_display()
```

当然，您也可以自行指定虚拟屏幕的分辨率和 DPI。

```python
vd = d.create_virtual_display(width=1080, height=1920, densityDpi=480)
```

## 在虚拟屏幕启动应用

默认情况下，新建的虚拟屏幕内没有任何应用在运行，所以它看起来是黑屏，所以您需要先在虚拟屏幕内启动一个应用，您可以使用下面的方式在虚拟屏幕内启动一个应用。

```python
app = vd.application("com.android.settings")
app.start()
```

```{tip}
您可以看到，使用方式和标准的 `d.xxx` 使用方式很像，您甚至无需做过多的改动即可将现有代码从 `d.xx` 切换到 `vd.xx` 以使您的脚本无感切换到虚拟屏幕。
```

## 在虚拟屏幕内自动化


您可以直接查看其他自动化接口的相关章节如 [基础自动化](./ui-basics.md)、[界面进阶](./ui-advanced.md) 等，使用上与他们完全无异，甚至您只需要在当前的代码上稍作改动即可将虚拟屏幕自动化能力完全迁移到您的脚本上。您可以参考以下代码，只需要将原本的 `d` 替换为 `create_virtual_display` 创建的实例即可。

```{attention}
虚拟屏幕生成的 vd 实例只包含了自动化及相关动作，设置代理等会产生全局效果的方法仍然需要您通过原始的 d 实例访问，对于属于自动化类别的接口但是会产生全局效果的，则会输出 WARNING 信息。
```

```python
# 将原始的 d 实例替换为虚拟屏幕实例
_d = Device("example.local")
d = _d.create_virtual_display()

# 原来的逻辑代码
app = d.application("com.android.settings")
app.start()
...
d(textContains="WLAN").click()
...

# 这里定义的 Watcher 只会对虚拟屏幕产生作用
d.set_watcher_loop_enabled(True)
d.register_none_op_watcher("RecordElementAppearTimes", [Selector(textContains="WLAN")])
d.set_watcher_enabled("RecordElementAppearTimes", True)
# ...
d.screenshot(100).save("screenshot.jpeg")
# ...

# 释放虚拟屏幕
d.release_virtual_display()
```

您也可以使用 with 上下文，这样会在代码块结束后自动销毁相关资源。

```python
with d.create_virtual_display() as vd:
    do_someting(vd)
```