Android13 使用WindowManager ActivityEmbedding平行视窗
简介
系统是由公司内部定制开发,在Android13上使用ActivityEmbedding平行视窗出现无作用,本文主要与系统沟通处理恢复使用平行视窗功能
原因分析
这里就不介绍平行视窗的功能使用了,可以参考官网的文档与demo
文档入口
官方Demo
1、定位无法使用原因
运行后查看控制台打印
2023-07-24 19:50:53.059 8568-8568/com.example.activityembedding D/EmbeddingBackend: No supported embedding extension found
2023-07-24 19:50:53.114 8568-8568/com.example.activityembedding D/WindowInitializer: create: splitSupportStatus = SplitSupportStatus: UNAVAILABLE
主要是这两句,可以看到提示说没有找到embedding extension扩展的库,导致无法使用
其实到这基本就定位到原因了,让系统把需要jar编译到系统内即可
2、接着定位出现这个打印的原因
SplitController
//省略..
/**
* Obtains an instance of [SplitController].
*
* @param context the [Context] to initialize the controller with
*/
@JvmStatic
fun getInstance(context: Context): SplitController {
val backend = EmbeddingBackend.getInstance(context)
return SplitController(backend)
}
//省略..
EmbeddingBackend
//省略..
@JvmStatic
@RestrictTo(RestrictTo.Scope.LIBRARY)
fun getInstance(context: Context): EmbeddingBackend {
return decorator(ExtensionEmbeddingBackend.getInstance(context))
}
//省略..
ExtensionEmbeddingBackend
//省略...
fun getInstance(context: Context): EmbeddingBackend {
if (globalInstance == null) {
globalLock.withLock {
if (globalInstance == null) {
val applicationContext = context.applicationContext
val embeddingExtension = initAndVerifyEmbeddingExtension(applicationContext)
globalInstance = ExtensionEmbeddingBackend(
applicationContext,
embeddingExtension
)
}
}
}
return globalInstance!!
}
/**
* Loads an instance of [androidx.window.extensions.embedding.ActivityEmbeddingComponent]
* implemented by OEM if available on this device. This also verifies if the loaded
* implementation conforms to the declared API version.
*/
private fun initAndVerifyEmbeddingExtension(
applicationContext: Context
): EmbeddingInterfaceCompat? {
var impl: EmbeddingInterfaceCompat? = null
try {
if (isExtensionVersionSupported(ExtensionsUtil.safeVendorApiLevel) &&
EmbeddingCompat.isEmbeddingAvailable()
) {
impl = EmbeddingBackend::class.java.classLoader?.let { loader ->
EmbeddingCompat(
EmbeddingCompat.embeddingComponent(),
EmbeddingAdapter(PredicateAdapter(loader)),
ConsumerAdapter(loader),
applicationContext
)
}
// TODO(b/190433400): Check API conformance
}
} catch (t: Throwable) {
if (EmbeddingCompat.DEBUG) {
Log.d(TAG, "Failed to load embedding extension: $t")
}
impl = null
}
if (impl == null) {
if (EmbeddingCompat.DEBUG) {
Log.d(TAG, "No supported embedding extension found")
}
}
return impl
}
//省略..
EmbeddingCompat
//省略...
fun isEmbeddingAvailable(): Boolean {
return try {
EmbeddingCompat::class.java.classLoader?.let { loader ->
SafeActivityEmbeddingComponentProvider(
loader,
ConsumerAdapter(loader),
WindowExtensionsProvider.getWindowExtensions(),
).activityEmbeddingComponent != null
} ?: false
} catch (e: NoClassDefFoundError) {
if (DEBUG) {
Log.d(TAG, "Embedding extension version not found")
}
false
} catch (e: UnsupportedOperationException) {
if (DEBUG) {
Log.d(TAG, "Stub Extension")
}
false
}
}
//省略..
SplitController在初始化时会需loader扩展的库存不存在,不存在最后会返回No supported embedding extension found
在 ExtensionEmbeddingBackend EmbeddingCompat.isEmbeddingAvailable() 有做类检查,目前定位出来就是加载不到对应的jar导致返回false后无法使用平行视窗功能;
3、解决办法
系统需要编译集成的jar,可以参考下方文档
官方文档
设备上启用androidx.window.extensions和androidx.window.sidecar包并设置persist.wm.extensions.enabled属性
系统编译是会直接编译出来androidx.window.extensions和androidx.window.sidecar这两个jar的,让系统根据文档处理即可
系统编译集成后进入原生设置就可以看到已经是平行视窗的方式显示了
结尾
• 感谢Android Developer
• 感谢系统编译集成