前言
我发现很多Android程序员写代码时,都喜欢把业务逻辑和UI的更新展示这两块代码都交集在Activity类上,最终往往会产出非常复杂或者上千行代码的类。但如果在开始做一个功能时,就把各种扩展和优化都考虑尽了,也不切实际,而且也有点过度设计的意味。也许因为这个原因,很多人在写代码时就干脆不考虑设计了,直接混在一起要哪块写哪块。
Google也许也看到了这个问题,在Android 3.0版本引进了Fragment,使用官方的support包(android-support-v4)也可以支持在3.0以前的版本使用。之前有一次老外的电话面试,也问到了Fragment方面的问题,那时Fragment刚面世不久,我发现老外都比较潮,喜欢尝试新的东西。
面试题:两个Fragment之间如何进行通信?
先说一下Fragment,中文可以叫片段,其实我们也可以把它理解成一个组件,它有自己的生命周期(回调函数),可以组织UI和业务逻辑。但它不像Android的四大组件(Activity, Service, BroadcastReceiver和ContentProvider)那样可以独立存在,它必须要依附于Activity,由Activity中的FragmentManager实例来管理它的生命周期。
Google最初引入Fragment主要是为了给大屏幕(如平板电脑)上更加动态和灵活的 UI 设计提供支持,看一下下图你就明白了:
我们可以在多个Activity中重复使用某个片段,并且可以按我们的需求把不同的片段组合在一个界面中,好处显而易见,减少工作量提高了代码的可重用性。
也就是说每个片段是相互独立的,如上图所示,Fragment A并不知道这个Activity中是否存在Fragment B。这样一来就会产生Fragment之间通信的问题(比如Fragment A点击了列表的一项,Fragment B的内容要进行更新),当然这个问题的答案并不是唯一的,有很多种做法。不过,最基础的做法你应该了解一下,就是通过Activity进行通信。
尽管Fragment是作为独立于Activity的对象实现,并且可在多个Activity内使用,但片段的给定实例会直接绑定到包含它的 Activity。具体地说,片段可以通过getActivity()访问Activity实例。
同样地,Activity也可以使用findFragmentById()或findFragmentByTag(),通过从FragmentManager获取对Fragment的引用来调用片段中的方法。
知道这些基础,你应该很清楚怎么进行通信了。不过我们建议的方式是面向接口编程,在Fragment中getActivity获取到的Activity实例应该是实现了我们某个接口的实例,即在Fragment的代码中不应该出现某个具体的Activity类。
Fragment的生命周期
如果你喜欢使用Fragment,一定要清楚这些生命周期的方法,哪个方法会创建视图(View),哪个会销毁视图,这样才能更好的使用它们。
先来看看官方的Fragmenet生命周期和Activity生命周期的对应关系图:
是不是觉得,好像也没有多复杂,只是在一些对应的Activity生命周期方法上进行了细分。
我们再看看反对使用Fragment的人是如何看待Fragment的生命周期的:
是不是头都大了?简单地说Fragment的生命周期并不像官方描述的那样简单,感兴趣的朋友可以看看这篇文章:我为什么主张反对使用Android Fragment。
Fragment虽然在某种程度上实现了代码复用,但并没有将UI和逻辑分离,而且引入了复杂的生命周期,在一定程度上也限制了它的使用。如Fragment嵌套Fragment可能会遇到嵌套的Fragment接收不到onActivityResult事件之类的问题。
不过,我也看到有人是这样使用Fragment的,创建一个没有UI的Fragment仅将它做为保存状态的工具使用。因为Fragment也有onSaveInstanceState方法,可以在里面对状态进行处理,而且系统回收Activity后再使用Activity时会帮我们恢复Fragment的状态。
关于Fragment还有很多细节,如果面试者经常使用的话,还可以问问“如何管理Fragment回退栈”或者“FragmentTransaction中remove和detach的区别”等问题。
小结
其实我也不喜欢用Fragment,因为我发现写Fragment和写Activity的感觉是一样的,UI加逻辑,也许是在为我面对的很多项目都不需要考虑平板的原因。不过即使考虑平板,我们一样可以通过自定义的View去实现。有时候我们使用Fragment,是因为考虑到使用它进行界面切换比Activity切换的代价要小很多。
面试时,面试者不一定能记起所有的细节,但我认为一些基础机制(或原理或者默认习俗)都是应该了解的,不然我会认为面试者不是经历的项目太少,就是没有进行系统性的学习,简单说就是,你可以没有使用过Fragment(这并不丢人),但你一定要了解一下Fragment是什么东西吧?
在现在这个金三银四的面试季,Fragment在面试中是必问到的知识,我自己在网上也搜集了很多资料做成了文档和架构视频资料免费分享给大家【包括高级UI、性能优化、架构师课程、NDK、Kotlin、混合式开发(ReactNative+Weex)、Flutter等架构技术资料】,希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
网友评论