能否使用ActivityScenario在Activity实例化和onCreate调用之间进行拦截?
解决方案
可以通过ActivityScenario/ActivityScenarioRule提供的官方接口实现该需求,核心是在Activity实例化完成后、onCreate生命周期触发前插入自定义操作,两种常用实现方式如下:
方式1:自定义ActivityFactory注入
在构造ActivityScenario或ActivityScenarioRule时传入自定义的ActivityFactory,即可接管Activity的实例化流程,在系统调用onCreate前完成你需要的操作:
直接使用ActivityScenario示例(Kotlin)
val testIntent = Intent(ApplicationProvider.getApplicationContext(), TargetActivity::class.java) ActivityScenario.launch<TargetActivity>( testIntent, object : ActivityScenario.ActivityFactory<TargetActivity> { override fun instantiate(classLoader: ClassLoader, className: String, intent: Intent?): TargetActivity { // 先完成Activity实例化 val activity = super.instantiate(classLoader, className, intent) as TargetActivity // 此处执行onCreate前的操作,仅支持成员变量赋值、mock注入等不依赖Context的操作 activity.mockDependency = TestMockModule.getMockService() activity.testFlag = true // 返回实例给系统执行后续生命周期 return activity } } )
使用ActivityScenarioRule示例(Kotlin)
@get:Rule val activityRule = ActivityScenarioRule( TargetActivity::class.java, null, // 可传入自定义启动Intent object : ActivityScenario.ActivityFactory<TargetActivity> { override fun instantiate(classLoader: ClassLoader, className: String, intent: Intent?): TargetActivity { val activity = super.instantiate(classLoader, className, intent) as TargetActivity // 插入onCreate前操作逻辑 return activity } } )
方式2:手动控制生命周期状态
你也可以启动Activity时指定初始状态为INITIALIZED,此时Activity仅完成实例化还未触发任何生命周期回调,执行完自定义操作后再手动推进生命周期到onCreate:
val scenario = ActivityScenario.launchActivityForResult<TargetActivity>( testIntent, Lifecycle.State.INITIALIZED ) // 执行onCreate前的自定义操作 scenario.onActivity { activity -> activity.someField = testValue } // 手动推进生命周期,触发onCreate流程 scenario.moveToState(Lifecycle.State.CREATED) // 后续可按需推进到RESUMED等状态 scenario.moveToState(Lifecycle.State.RESUMED)
注意事项
- 不要在
onCreate前的操作里调用刚实例化的Activity的Context相关方法,此时Activity还未完成Attach到系统,Context未初始化,需要全局Context可以通过ApplicationProvider.getApplicationContext()获取 - 自定义ActivityFactory时必须返回构造完成的Activity实例,否则系统会抛出实例化异常
内容的提问来源于stack exchange,提问作者Nilzor
相关产品推荐
相关产品推荐

