Viewholder内部会议纪要以及fragment相关知识总结
2017-10-16 14:00
441 查看
内部组会上讲了一下viewHolder在解耦方面的应用( 使用ViewModel解耦页面(含源码分析))。在讲解和讨论过程中,发现对fragment的一些知识点理解不到位。会后查看了相关的知识点并总结了一下:
使用 Viewholder方式:ViewModelProviders.of(宿主activity).get(A.class) 其中A extend ViewHolder
用处:一个activty内,任何block,adapter,view类中都可“无显式耦合”的获得彼此间的数据。举例:我们可以在activty一开始就存一个movieId的viewHolder,那么这个activty涉及的所有类中都可以使用context来获取movieId。这对于埋点等都是很好帮助的,避免了级联引用。
大致原理:ViewModelProviders.of()用于获取ViewModelProvider实例。ViewModelProvider中含有一个ViewModelStore,ViewModelStore是用来存储viewModel的(ViewModelStore内部含有map)。ViewModelStore对于宿主activity是唯一的。其实质是宿主activity中HoldFragment的一个成员变量。
更正:
旋转屏幕时,activty内置的HolderFragment不会被销毁(为什么旋转时不会被销毁,是因为在HolderFragment中指定了setRetainInstance(true);),且fragmentManager.findFragmentByTag(HOLDER_TAG)还是能够找到内置的HolderFragment。
因为HolderFragment中存储map ,所以这就解释了为什么activity在旋转的时候,viewModel不会丢失。
旋转屏幕时,原来的activty会被销毁,重新生成一个新的activty。昨天提到的HolderFragmentManager中map
类型的成员变量mNotCommittedActivityHolders不是为了屏幕旋转问题而生的。他里面对应的Entry的生存时间是“new出来HolderFragment时刻 到HolderFragment执行onCreate()执行完的时刻”,如果HolderFragment始终没有执行onCreate()那么等到activty销毁的时候,会清除mNotCommittedActivityHolders中对应的Entry。既然不是为屏幕旋转问题而生,那为什么要弄个这个呢?因为fragment在commit()以后不会立即执行commit()动作,会使用handler来把这次的commit放到主线程消息队列中,等待执行。所以如果fragment在没有真正执行commit()动作的时候,使用manager.findFragmentByTag(HOLDER_TAG)找不到对应的HolderFragment,那么用mNotCommittedActivityHolders这样方式来兜底。
一些生命周期的执行顺序执行
在Activity中onCreate()中执行addFragent()的commit动作(使用commit()或commitAllowingStateLoss())时,
Activity的onCreate()、
Fragment的onAttach()、
activty的onAttachFragment()、
Fragment的onCreate()的执行顺序:
Activity#onCreate()->
Fragment#onAttach()->
activty#onAttachFragment->
Fragment#onCreate()
源码注释:
commit立即执行
使用commitNow()和commitNowAllowingStateLoss()来代替commit()或commitAllowingStateLoss()。或使用commit()/commitAllowingStateLoss()->
executePendingTransactions()
这样不用使用handler分发,而是立即执行。
commit()和commitAllowingStateLoss()区别
在Activity的状态被保存之后(执行了onSaveInstanceState(),这个方法在onStop()之后可能执行),提交commit操作是没有被Activity所记录的,恢复时也就没办法恢复这些提交操作,所以官方文档称这个方法是一个危险的操作。如果这些提交操作不是很重要,丢不丢失无所谓的话你就可以使用commitAllowingStateLoss()这个方法了。
所以如果onSaveInstanceState()之后,再执行commit,那么就会异常,这时候得使用commitAllowingStateLoss()。
使用 Viewholder方式:ViewModelProviders.of(宿主activity).get(A.class) 其中A extend ViewHolder
用处:一个activty内,任何block,adapter,view类中都可“无显式耦合”的获得彼此间的数据。举例:我们可以在activty一开始就存一个movieId的viewHolder,那么这个activty涉及的所有类中都可以使用context来获取movieId。这对于埋点等都是很好帮助的,避免了级联引用。
大致原理:ViewModelProviders.of()用于获取ViewModelProvider实例。ViewModelProvider中含有一个ViewModelStore,ViewModelStore是用来存储viewModel的(ViewModelStore内部含有map)。ViewModelStore对于宿主activity是唯一的。其实质是宿主activity中HoldFragment的一个成员变量。
更正:
旋转屏幕时,activty内置的HolderFragment不会被销毁(为什么旋转时不会被销毁,是因为在HolderFragment中指定了setRetainInstance(true);),且fragmentManager.findFragmentByTag(HOLDER_TAG)还是能够找到内置的HolderFragment。
因为HolderFragment中存储map ,所以这就解释了为什么activity在旋转的时候,viewModel不会丢失。
旋转屏幕时,原来的activty会被销毁,重新生成一个新的activty。昨天提到的HolderFragmentManager中map
类型的成员变量mNotCommittedActivityHolders不是为了屏幕旋转问题而生的。他里面对应的Entry的生存时间是“new出来HolderFragment时刻 到HolderFragment执行onCreate()执行完的时刻”,如果HolderFragment始终没有执行onCreate()那么等到activty销毁的时候,会清除mNotCommittedActivityHolders中对应的Entry。既然不是为屏幕旋转问题而生,那为什么要弄个这个呢?因为fragment在commit()以后不会立即执行commit()动作,会使用handler来把这次的commit放到主线程消息队列中,等待执行。所以如果fragment在没有真正执行commit()动作的时候,使用manager.findFragmentByTag(HOLDER_TAG)找不到对应的HolderFragment,那么用mNotCommittedActivityHolders这样方式来兜底。
一些生命周期的执行顺序执行
在Activity中onCreate()中执行addFragent()的commit动作(使用commit()或commitAllowingStateLoss())时,
Activity的onCreate()、
Fragment的onAttach()、
activty的onAttachFragment()、
Fragment的onCreate()的执行顺序:
Activity#onCreate()->
Fragment#onAttach()->
activty#onAttachFragment->
Fragment#onCreate()
源码注释:
/** * Called when a Fragment is being attached to this activity, immediately * after the call to its {@link Fragment#onAttach Fragment.onAttach()} * method and before {@link Fragment#onCreate Fragment.onCreate()}. */ public void Activity#onAttachFragment(Fragment fragment) { }
commit立即执行
使用commitNow()和commitNowAllowingStateLoss()来代替commit()或commitAllowingStateLoss()。或使用commit()/commitAllowingStateLoss()->
executePendingTransactions()
这样不用使用handler分发,而是立即执行。
commit()和commitAllowingStateLoss()区别
在Activity的状态被保存之后(执行了onSaveInstanceState(),这个方法在onStop()之后可能执行),提交commit操作是没有被Activity所记录的,恢复时也就没办法恢复这些提交操作,所以官方文档称这个方法是一个危险的操作。如果这些提交操作不是很重要,丢不丢失无所谓的话你就可以使用commitAllowingStateLoss()这个方法了。
所以如果onSaveInstanceState()之后,再执行commit,那么就会异常,这时候得使用commitAllowingStateLoss()。
相关文章推荐
- Fragment的生命周期以及相关库函数的执行流程总结
- Android Fragment使用总结以及与Viewpager相结合使用
- jquery相关校验以及jquery其他知识总结
- (20)WEB的相关知识以及JSP入门基础知识点总结
- 工作中用到了webview 下面把webview相关的知识进行一下总结:
- 工作中用到了webview 下面把webview相关的知识进行一下总结:
- 数据库相关知识以及经验总结
- 【Android 自定义控件】自定义View相关知识总结
- 关于简单的自定义view以及相关知识
- ViewPager和Fragment实现滑动标签页步骤以及方法总结
- 总结Nib(xIB)、File's owner、NSBundle、loadView/viewDidLoad、initWithNibName的相关基础知识
- Android Studio插件LayoutCreator在Activity/Fragment中自动生成findViewById等布局相关初始化代码 或者在Adapter中自动生成ViewHolder
- Android Fragment使用总结以及与Viewpager相结合使用
- View相关知识学习总结
- Hadoop2.7.0 以及相关linux知识(自己总结经验)
- 【Android Fragment相关】Fragment基础知识总结
- 关于android view属性的归属以及如何在代码中设置相关属性总结
- webView中用到横竖屏切换,引起activity重构以及Fragment出现监听失效问题
- IOS -- ViewController的LoadView和ViewDidLoad方法相关知识总结
- 自定义Android FragmentPagerAdapter中相关Fragment加载到ViewPager的一点说明