如何让ViewModel的init方法仅在特定Fragment调用时执行?
解决方案
ViewModel的init方法是在实例创建时必然执行的,没办法直接跳过。要实现“仅在特定Fragment中执行目标逻辑”,得把逻辑从init里抽出来,交给调用方主动触发。
步骤1:重构ViewModel
把init里的埋点逻辑移到一个公开方法中,移除init里的调用:
@HiltViewModel class NotificationViewModel @Inject constructor( private val screenAnalytics: SegmentScreenAnalytics, ) : BaseViewModel() { // 把原来init里的逻辑抽成公开方法 fun trackNotificationsScreen() { screenAnalytics.screenNotifications() } }
步骤2:在需要执行逻辑的Fragment中主动调用
比如那个需要启动时执行埋点的Fragment:
@AndroidEntryPoint class NotificationFragment : BaseFragment(R.layout.fragment_notification) { private val notificationViewModel: NotificationViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 主动调用埋点方法 notificationViewModel.trackNotificationsScreen() } }
步骤3:不需要执行逻辑的Fragment直接使用ViewModel
像你的WelcomeFragment,只创建ViewModel,不调用埋点方法即可:
@AndroidEntryPoint class WelcomeFragment : BaseFragment(R.layout.fragment_welcome) { private val notificationViewModel: NotificationViewModel by viewModels() // 这里不需要调用trackNotificationsScreen(),自然不会执行埋点逻辑 }
为什么不能直接跳过init?
只要ViewModel的实例被创建,构造函数执行完毕后就会自动触发init代码块。不管两个Fragment共享同一ViewModel实例(同作用域场景)还是各自创建实例,init都会执行。所以唯一可控的方式就是把逻辑抽离,让调用方决定是否执行。
内容的提问来源于stack exchange,提问作者Carmen Gordillo
相关产品推荐
相关产品推荐

