Android

Window嵌入Activity

2022-09-28  本文已影响0人  freelifes

1、简介

大屏幕设备能够让用户看到更多内容、执行更多操作、体验更多功能。大显示屏提供了同时运行多个 activity 或同一 activity 的多个实例的机会

2、使用

2.1 项目依赖库中加入
Implementation("androidx.window:window:1.0.0-beta03")
2.2 配置xml 定义配置分屏的activity,绝对不分屏的activity。

<SplitPairRule
       window:finishPrimaryWithSecondary="adjacent"
       window:finishSecondaryWithPrimary="never"
       window:splitMinWidth="300dp"
       window:splitRatio="0.3">
       <SplitPairFilter
           window:primaryActivityName="com.mahao.customview.multiwindow.ListActivity"
           window:secondaryActivityName="com.mahao.customview.multiwindow.DetailActivity" />

       <SplitPairFilter
           window:primaryActivityName="*"
           window:secondaryActivityAction="android.intent.action.VIEW"
           window:secondaryActivityName="*/*" />
   </SplitPairRule>

<SplitPairRule
       window:finishPrimaryWithSecondary="never"
       window:finishSecondaryWithPrimary="adjacent"
       window:splitMinWidth="300dp"
       window:splitRatio="0.5">
       <SplitPairFilter
           window:primaryActivityName="com.mahao.customview.multiwindow.DetailActivity"
           window:secondaryActivityName="com.mahao.customview.multiwindow.ItemActivity" />
   </SplitPairRule>

2.3 使用xml,规则定义必须在启动activity之前。如果更改配置,必须重新启动activity。所以我们可以更改xml之后,销毁当前activity,监听当前activity的生命周期,再重新启动这个activity。因为需要在activity启动之前,所以选择application或者通过startup中调用。

 <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">
            <meta-data
                android:name="com.mahao.customview.ExampleWindowInitializer"
                android:value="androidx.startup" />
   </provider>

class ExampleWindowInitializer : Initializer<SplitController> {
    private  val TAG = "ExampleWindowInitialize"
    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
        return arrayListOf()
    }

    override fun create(context: Context): SplitController {
        SplitController.initialize(context,R.xml.multi_window)
        var splitRules = SplitController.getInstance().getSplitRules()
        Log.d(TAG, "create: " + splitRules.size)
        return SplitController.getInstance()
    }
}

3、使用场景

image.png
image.png
image.png

这些场景是由下面2个参数控制的:

finishPrimaryWithSecondary : Secondary销毁时
never : Primary 从不销毁
always :Primary 总是销毁
adjacent :Primary并排的一个销毁了就会销毁

finishSecondaryWithPrimary : Primary 销毁时
never : Secondary 从不销毁
always : Secondary 总是销毁
adjacent: Secondary并排的一个销毁了就会销毁

4、源码解析

4.1、解析

  @JvmStatic
        fun initialize(context: Context, staticRuleResourceId: Int) {
            val parser = SplitRuleParser()
            val configs = parser.parseSplitRules(context, staticRuleResourceId)
            val controllerInstance = getInstance()
            controllerInstance.setStaticSplitRules(configs ?: emptySet())
        }

4.2、转换规则为OEM

 private fun translateSplitPairRule(
        rule: SplitPairRule,
        predicateClass: Class<*>
    ): OEMSplitPairRule {
        val builder = SplitPairRuleBuilder::class.java.getConstructor(
            predicateClass,
            predicateClass,
            predicateClass
        ).newInstance(
            translateActivityPairPredicates(rule.filters),
            translateActivityIntentPredicates(rule.filters),
            translateParentMetricsPredicate(rule)
        )
            .setSplitRatio(rule.splitRatio)
            .setLayoutDirection(rule.layoutDirection)
            .setShouldClearTop(rule.clearTop)
            .setFinishPrimaryWithSecondary(rule.finishPrimaryWithSecondary)
            .setFinishSecondaryWithPrimary(rule.finishSecondaryWithPrimary)
        return builder.build()
    }

4.3、设置规则给OEM厂商最终处理。

EmbeddingAdapter

internal interface EmbeddingInterfaceCompat {

    fun setSplitRules(rules: Set<EmbeddingRule>)

    fun setEmbeddingCallback(embeddingCallback: EmbeddingCallbackInterface)

    interface EmbeddingCallbackInterface {
        fun onSplitInfoChanged(splitInfo: List<SplitInfo>)
    }

    fun isActivityEmbedded(activity: Activity): Boolean
}

internal class EmbeddingCompat constructor() : EmbeddingInterfaceCompat {

    override fun setSplitRules(rules: Set<EmbeddingRule>) {
        val r = adapter.translate(rules)
        embeddingExtension.setEmbeddingRules(r)
    }
}

1、SplitController类 : 分屏控制类。
2、EmbeddingBackend类 :分屏代理类。
3、EmbeddingInterfaceCompat类:真正的实现类。

上一篇下一篇

猜你喜欢

热点阅读