本文档详细介绍了 scrcpy 中为确保跨不同 Android 版本和设备特定问题的兼容性而实现的注意事项。scrcpy 的服务器组件需要与各种 Android 系统 API 进行交互,其中许多 API 具有特定于版本的行为或限制。本页解释了兼容性挑战以及为克服这些挑战而实施的技术解决方案。
有关用户视角的设备特定问题,请参阅 设备兼容性。
Scrcpy 实现了一系列注意事项,以确保服务器能够在各种 Android 设备和版本上正常运行。这些注意事项主要解决了与以下问题相关的问题:
来源:server/src/main/java/com/genymobile/scrcpy/Workarounds.java1-314 server/src/main/java/com/genymobile/scrcpy/FakeContext.java1-94
Scrcpy 的注意事项主要使用 Java 反射来:
该实现包含许多注解,例如 @SuppressLint("PrivateApi,BlockedPrivateApi,SoonBlockedPrivateApi,DiscouragedPrivateApi"),以承认这些访问非公共 API 的技术。
来源:server/src/main/java/com/genymobile/scrcpy/Workarounds.java25-57 server/src/main/java/com/genymobile/scrcpy/FakeContext.java14-57
scrcpy 服务器需要正确初始化的主 Looper 来正确处理事件。某些设备在创建输入 Surface 时会创建 Handler,这需要准备好 Looper。
来源:server/src/main/java/com/genymobile/scrcpy/Workarounds.java31-90
注意事项设置了一个 ActivityThread 实例,该实例通常由系统为常规 Android 应用程序创建。这是必需的,因为一些系统服务会验证调用者是否具有有效的 ActivityThread。
来源:server/src/main/java/com/genymobile/scrcpy/Workarounds.java28-53
Scrcpy 创建了一个模拟的应用程序上下文和信息,许多 Android API 需要它才能正常运行。这包括:
ApplicationInfoActivityThread.AppBindDataApplication 实例该代码根据设备品牌有条件地应用某些注意事项,以避免兼容性问题。
来源:server/src/main/java/com/genymobile/scrcpy/Workarounds.java59-133 server/src/main/java/com/genymobile/scrcpy/FakeContext.java57-93
在 Android 12 及更高版本上,某些三星设备需要正确初始化的 ConfigurationController,以避免在 DisplayManagerGlobal.getDisplayInfoLocked() 中崩溃。
来源:server/src/main/java/com/genymobile/scrcpy/Workarounds.java136-153
为创建 AudioRecord 实例实现了一个复杂的事项,该实例可在不同的 Android 版本(尤其是 Vivo ROM)上运行。该事项:
AudioRecord这可以绕过设备制造商进行的自定义修改,否则这些修改会阻止音频捕获工作。
| Android 版本 | 实现方法 |
|---|---|
| < Android 12 | 使用带包名参数的 native_setup |
| Android 12-13 | 使用通过 Parcel 的 AttributionSource 调用 native_setup |
| Android 14+ | 与 12-13 相同,并增加了 halInputFlags 参数 |
来源:server/src/main/java/com/genymobile/scrcpy/Workarounds.java166-313
该 FakeContext 类为服务器组件提供了类似 shell 的上下文,用于与需要上下文的 Android API 进行交互。它:
ContextWrapper 并包装了系统上下文ContentResolver 实现com.android.shell)AttributionSource来源:server/src/main/java/com/genymobile/scrcpy/FakeContext.java1-94 server/src/main/java/android/content/IContentProvider.java1-6
Scrcpy 在整个注意事项中实现了版本检查,以处理 Android 版本之间的差异。
| Android 版本 | 关键 API 级别常量 | 兼容性考虑因素 |
|---|---|---|
| Android 12+ | API_31_ANDROID_12 | 需要 ConfigurationController 设置,使用 AttributionSource |
| Android 14+ | API_34_ANDROID_14 | 为 AudioRecord 的 native_setup 添加了额外参数 |
该实现使用 AndroidVersions 类来定义这些常量,并使版本比较更加易读。
来源:server/src/main/java/com/genymobile/scrcpy/Workarounds.java59-77 server/src/main/java/com/genymobile/scrcpy/Workarounds.java237-284
这些注意事项在服务器启动期间初始化,确保兼容性层在任何其他组件启动之前就已到位。
注意事项的初始化发生在 Workarounds 类的静态块中,确保主 Looper 和 ActivityThread 设置尽早完成,并在显式调用时应用额外的注意事项。
来源:server/src/main/java/com/genymobile/scrcpy/Workarounds.java31-53 server/src/main/java/com/genymobile/scrcpy/Workarounds.java59-77