Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-03-11: Activity 与 Fragment 之间常见的几种通信方式?

Moosphan opened this issue · comments

2019-03-11: Activity 与 Fragment 之间常见的几种通信方式?
commented

1.接口方式
2.Bundle
3.广播
4.Handler貌似也是可以的但是不太确定
5.eventbus
6.文件。。。。

楼上的正解,就是楼主你面试的时候真有人这样问吗

1.接口方式
2.Bundle
3.广播
4.Handler貌似也是可以的但是不太确定
5.eventbus
6.文件。。。。

偏好设置文件,数据库,ContentProvider,RxJava订阅是不是也可以?

这个问题不太科学,一般也不会这样问,说到底就是两个普通的JAVA对象相互都持有对方的引用,直接回调就成,哪还需要什么别的通信方式,很简单的问题别搞复杂了

①采用Bundle的方式
在activity中建一个bundle,把要传的值存入bundle,然后通过fragment的setArguments(bundle)传到fragment,在fragment中,用getArguments接收。
②采用接口回调的方式
③EventBus的方式

  1. 直接当做普通对象传递数据有问题。
  2. 为什么官方推荐采用setArguments(bundle)的方式,因为fragment存在回收的情况,当再次重建时会通过空参构造方法反射出新的fragment。
  3. 这也就是为什么建议保留空参构造方法。同时你需要通过savedInstanceState去恢复数据。

引出另外一个问题:大家是怎么处理activity会fragment重建后数据恢复问题的?线上这个问题必现。不会都是老老实实去一个一个恢复数据的吧?

commented

viewModel 做数据管理,activity 和 fragment 公用同个viewModel 实现数据传递

确确实实有遇到这样问的公司 Activity 与 Fragment Fragment 与 Fragment之间通信 但这确实不是一个好的问题

1 互相持有对方的引用 直接调用
2 Broadcast Receiver
3 EventBus
4 设置接口间接调用
5 Bundle

这个问题不太科学,一般也不会这样问,说到底就是两个普通的JAVA对象相互都持有对方的引用,直接回调就成,哪还需要什么别的通信方式,很简单的问题别搞复杂了

1。我也觉得,直接可以拿到 activity 的,activty也可以拿到 fragment,
直接定义方法调用不行吗??注意null指针
2。他们讨论的 bundle,那个跟本问题没关系

最优方式,官方组件ViewModel。

官方组件ViewModel如何实现数据恢复,原理是什么?

Fragment 中的 setTargetFragment 相关的方法,让 Fragment 间耦合性太高,不太建议使用。另外还可以延伸一些面试题:

  1. Fragment 的使用,FragmentManager 对 Fragment 的管理;
  2. Fragment 的生命周期;
  3. Fragment 和 宿主Activity 的关系和交互。
  1. 直接当做普通对象传递数据有问题。
  2. 为什么官方推荐采用setArguments(bundle)的方式,因为fragment存在回收的情况,当再次重建时会通过空参构造方法反射出新的fragment。
  3. 这也就是为什么建议保留空参构造方法。同时你需要通过savedInstanceState去恢复数据。

引出另外一个问题:大家是怎么处理activity会fragment重建后数据恢复问题的?线上这个问题必现。不会都是老老实实去一个一个恢复数据的吧?

就是一个一个去恢复的

官方组件ViewModel如何实现数据恢复,原理是什么?

ViewModel 只能在 config 变化引起重建的时候恢复,在 内存不够等情况下 被销毁的时候并不能 恢复,
原理请百度 onRetainNoConfigInstance,如果我方法名没写错的话=.=

1、对于Activity和Fragment之间的相互调用
(1)Activity调用Fragment
直接调用就好,Activity一般持有Fragment实例,或者通过Fragment id 或者tag获取到Fragment实例
(2)Fragment调用Activity
通过activity设置监听器到Fragment进行回调,或者是直接在fragment直接getActivity获取到activity实例
2、Activity如果更好的传递参数给Fragment
如果直接通过普通方法的调用传递参数的话,那么在fragment回收后恢复不能恢复这些数据。google给我们提供了一个方法 setArguments(bundle) 可以通过这个方法传递参数给fragment,然后在fragment中用getArguments获取到。能保证在fragment销毁重建后还能获取到数据

使用Navigation组件,activity传参启动fragment
Bundle bundle = new Bundle();
Track musicTrack = (Track) playingModel;
bundle.putParcelable("musicTrack", musicTrack);
findNavController(this, R.id.fragment).navigate(R.id.musicDetailFragment, bundle, MyApp.navVerticalOptions);

  1. 直接当做普通对象传递数据有问题。
  2. 为什么官方推荐采用setArguments(bundle)的方式,因为fragment存在回收的情况,当再次重建时会通过空参构造方法反射出新的fragment。
  3. 这也就是为什么建议保留空参构造方法。同时你需要通过savedInstanceState去恢复数据。

引出另外一个问题:大家是怎么处理activity会fragment重建后数据恢复问题的?线上这个问题必现。不会都是老老实实去一个一个恢复数据的吧?

就是一个一个去恢复的

官方组件ViewModel如何实现数据恢复,原理是什么?

ViewModel 只能在 config 变化引起重建的时候恢复,在 内存不够等情况下 被销毁的时候并不能 恢复,
原理请百度 onRetainNoConfigInstance,如果我方法名没写错的话=.=

内存不够的ondestory这种情况会执行onClear() clear掉, 配置变化得ondestory不会的

这个问题不太科学,一般也不会这样问,说到底就是两个普通的JAVA对象相互都持有对方的引用,直接回调就成,哪还需要什么别的通信方式,很简单的问题别搞复杂了

被问到过

1,通过Bundle setArguments getArguments
2,通过EventBus
3,通过广播

现在官方只推荐两种方式:ViewModel 和 Fragment Result API