使用观察者模式完美解决activity与fragment通信问题

【Android】Fragment与Activity间通信知识总结 就是在MainActivity进行动态注册时,把data通过构造方法传参的形式传给fragment,所以要对fragment类进行修改。我这里有两个碎片在MainActivity上放着,并且他们各自都有一个按钮和文本,按钮用来发送数据,文本用来接收显示数据。这样,当数据发生变化时,我们可以通过这个变量来调用对应的实现,以通知数据变化。是一个用于携带数据的键值对集合,它可以保存各种类型的数据,本身是一个实现了。接口的类,因此它可以被序列化以便在组件之间传递。方法则是在视图创建完成后调用的,使用。 阅读详情

概述

通常来说,解决activity和fragment通信的问题。我们都是采用如下几种方式, 
handler,广播,EvnetBus,接口等。那么有没有一种更好的方式来实现呢,最近项目一只在使用Rx,这里参照了一下Rx的设计来解决如上问题。先来说说常用的几种方式。

handler方式

这是一种最不好的初级方式,在fragment中调用activity中的handler发送信息,activity处理信息。缺点也十分明显,耦合性极强,并且获取不了activity的反馈,总之体验十分不好。

广播

这是一种另类的玩法,个人感觉大材小用了。广播适用于一对多且接收者不明确的情况下, 
而且广播传播的信息需要实现序列化借口,总之是一种耗费性能的方式。

EvnetBus

EvnetBus作为一款事件总线存在,可以用于Action的传递,但是这种方式的缺点有:是用反射(对性能有影响),EvnetBus发送者和接受者分离严重,不好维护,且不可以获取activity反馈,也不是十分理想。

接口

之前处理这类问题一直也是适应这种方式,总体来讲还是很不错。但是也有缺点,当项目大了的时候,就需要定义很多的接口,这时候就容易混淆,不好维护。

新大陆

总结一下Rx的设计思路,Rx和设计模式中的观察者十分类似。activity和fragment通信,实质上就是所谓事件的传递和响应,只是这个事件是一个特殊的事件,就是可以执行的方法(js中function也可以是参数),那么如果activity需要监听fragment的事件,只需要观察其相应事件即可,fragment同理。

如果对观察者不熟悉的可以看一下:这就是观察者模式

Observable

public interface ObservableInterface<T, P, R> {

  /**
   * 根据名称注册观察者
   */
  void registerObserver(String name, T observer);

  /**
   * 根据名称反注册观察者
   */
  void removeObserver(String name);

  /**
   * 根据观察者反注册
   */
  void removeObserver(T observer);

  /**
   * 根据名称和观察者反注册
   */
  void removeObserver(String name, T observer);

  /**
   * 根据名称获取观察者
   */
  Set<T> getObserver(String name);

  /**
   * 清除观察者
   */
  void clear();

  /**
   * 通知观察者
   *
   * @param name 名称
   * @param p 参数
   * @return 返回值
   */

  R notify(String name, P... p);
}
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

Observer

public interface Function<Result, Param> {

  Result function(Param... data);
}
   
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

这里的Observer就是一个方法的抽象,包含 参数 和 返回值。在Activity和Fragment中传递的就是Fuction,在需要监听的地方注册事件,在适当的地方触发事件。下面看一下Observable的具体实现

ObservableManager

public class ObservableManager<Param, Result>
    implements ObservableInterface<Function, Param, Result> {

  private static final String TAG = "ObservableManager";
  private HashMap<String, Set<Function>> _mapping;
  private final Object _lockObj = new Object();
  private static ObservableManager _instance;

  public ObservableManager() {
    this._mapping = new HashMap<>();
  }

  public static ObservableManager newInstance() {
    if (_instance == null) _instance = new ObservableManager();
    return _instance;
  }

  @Override public void registerObserver(String name, Function observer) {
    synchronized (_lockObj) {
      Set<Function> observers;
      if (!_mapping.containsKey(name)) {
        observers = new HashSet<>();
        _mapping.put(name, observers);
      } else {
        observers = _mapping.get(name);
      }
      observers.add(observer);
    }
  }

  @Override public void removeObserver(String name) {
    synchronized (_lockObj) {
      _mapping.remove(name);
    }
  }

  @Override public void removeObserver(Function observer) {
    synchronized (_lockObj) {
      for (String key : _mapping.keySet()) {
        Set<Function> observers = _mapping.get(key);
        observers.remove(observer);
      }
    }
  }

  @Override public void removeObserver(String name, Function observer) {
    synchronized (_lockObj) {
      if (_mapping.containsKey(name)) {
        Set<Function> observers = _mapping.get(name);
        observers.remove(observer);
      }
    }
  }

  @Override public Set<Function> getObserver(String name) {
    Set<Function> observers = null;
    synchronized (_lockObj) {
      if (_mapping.containsKey(name)) {
        observers = _mapping.get(name);
      }
    }
    return observers;
  }

  @Override public void clear() {
    synchronized (_lockObj) {
      _mapping.clear();
    }
  }

  public Result notify(String name, Param... param) {
    synchronized (_lockObj) {
      if (_mapping.containsKey(name)) {
        Set<Function> observers = _mapping.get(name);
        for (Function o : observers) {
          return (Result) o.function(param);
        }
      }
      return null;
    }
  }
}
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82

这里才用了一个HashMap来存储所有Observer集合,触发事件后就轮询集合循序之行,这就是观察者其中之一的缺点,一个Observer可能阻塞,影响其他执行。

使用

Activity中注册Function事件,Fragment中出发Function事件,执行的到结果,反之亦然。

// 注册事件,Activity实现Function接口
ObservableManager.newInstance().registerObserver(FUNCTION_WITH_PARAM_AND_RESULT, this);
   
  • 1
  • 2
  • 1
  • 2
//触发事件,并获得返回值
Object notify = ObservableManager.newInstance()
        .notify(MainActivity.FUNCTION_WITH_PARAM_AND_RESULT, "我是fragment传到activity的参数1", fragmentActivity,
            fragmentResult);
   
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4
//事件执行,实现于Function接口
@Override public Object function(Object[] data) {
   String text = activityResult.getText().toString() + "\n\n\n";

   activityResult.setText(text + "fragment调用我成功,获取到参数 :" + Arrays.asList(data));

   return "我是activity的返回结果";
 }
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

最终效果:

activityfragment

示例代码:ActivityFragment

使用观察者模式完美解决activity与fragment通信问题


转自 http://blog.youkuaiyun.com/wbwjx/article/details/51587887

Android中Fragment与Activity的相互通信 Fragment向Activity通信:    实现Fragment向Activity通信的方法为在Fragment内部定义接口,在接口中定义要实现的方法,并在绑定的Activity中实现这个接口,在Fragment 的OnAttach方法中获得绑定的Activity对象,并将得到的Activity对象强制转化为接口对象,这样就可以在fragment中操作activity实现接口之后继承的方法,从 阅读详情

相关推荐

Android Fragment之间的通信处理

在某些情况下,需要在不同的Fragment之间进行通信和数据传递。本文将介绍一些常用的方法来处理Android Fragment之间的通信。通过定义一个接口,在其中定义需要传递的方法,然后让包含Fragment的Activity实现该接口。以上是三种常用的处理Android Fragment之间通信的方法,包括使用接口、观察者模式和Bundle。根据实际需求选择合适的方法来实现Fragment之间的通信,以便实现灵活和可扩展的应用程序。观察者模式是一种常用的设计模式,通过定义观察者和被观察者来实现通信。

2301_79326254的博客 341

Android中的观察者模式简单使用

观察者模式 “定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象都将得到通知,并自动更新”,可以理解成多个观察者向一个被观察者订阅消息,当被观察者发生改变时通知相应的观察者去作自己的事情。 Android 中的观察者实现java.util.Observer接口,被观察者继承java.util.Observable类。 ##使用步骤 1. 观察者实现Observer接口,重写u

TheBadWaka的博客 1998

Android项目源码基于FragmentRxJavaRetrofitGlideRealm开发框架

FastApp 是一个轻量级急速开发框架,基于 Fragment RxJava Retrofit 2.0 Glide Realm 构建,采用 Material Design 设计风格,帮助开发者快速构建轻量级应用。当然,由于本项目是为了说明博客中提到的一些问题,因此早期并未让其复杂化。另外,为了让它富有生机,给它起名为“师父说”本项目基于 Material Design RxJava Retrofit 2.0 Glide Realm 构建了一个良好 MVC 架构的客户端模型,对新手友好度更高。在这里我们使用了几个公共api快速搭建一个简单的新闻阅读类App。

RxJava(十三)RxJava导致Fragment Activity内存泄漏问题

一般我们在实际的开发中,RxJava和Retrofit2结合使用的比较多,因为他们可以无缝集成,例如我们下面的一个网络请求: public interface OtherApi { @GET("/timeout") Observable<Response> testTimeout(@Query("timeout") String timeout); } priv...

android开发笔记 1034

数据去重复_京东商品评论情感分析|文本数据预处理

本文爬取了十款热销手机的文本评论数据后,首先对文本评论数据做文本预处理,文本评论数据中存在大量的无价值信息,引入无用的文本数据,对其作情感分析,显然没有价值,得出的文本挖掘结果也不尽人意。所以对于文本评论数据先进行文本预处理是必不可少的一步,把大量的、冗余的、无价值的信息去除,可以极大提高文本数据的质量,精确文本分析结果。1 文本去重1.1文本去重的原因文本数据预处理时,首先应去除文本评论数据中反...

weixin_34556808的博客 2073

大数据之父_BIM先驱Charles (Chuck) M. Eastman逝世——致敬“BIM之父”

原标题:BIM先驱Charles (Chuck) M. Eastman逝世——致敬“BIM之父”BIM研究的先驱、佐治亚理工教授Charles (Chuck) M. Eastman于本周一(11月9日)在其Atlanta家中逝世。特转韩国Yonsei大学Ghang Lee教授的讣文以作纪念。过世原因未说明。BIM的出现是与当今时代科技的发展分不开的。在信息时代建筑发展面临的挑战巨大:建筑物越建越高...

weixin_39941262的博客 3302

Android 之路 (12) - RxLifecycle的集成

引言 引入Rx系列有一个非常大的缺陷:容易造成内存泄露,大多数都是忘记取消订阅而造成的,本篇就以RxLifecycle进行封装,在底层实现自动订阅与取消订阅。 正文 分析 我们在之前的Android 之路 (4) - 对RxJava2的简单封装中,在BasePresenter中有一个unDisposable的方法,该方法会在onDestroy和onDialogCance的时候调用,这已经从一定程度...

AndroidRookie 951

大语言模型(LLM)在组合优化中的新突破:LLM-LNS与FunSearch性能对比

本文深入探讨了大语言模型(LLM)在组合优化中的创新应用,重点对比了LLM-LNS与FunSearch两种方法的性能差异。研究表明,LLM-LNS在物流路径规划、资源调度等场景中展现出显著优势,其双层自演化架构能有效平衡探索与利用,相比传统方法提升效率约43%。文章还提供了实践选择指南,帮助开发者根据具体需求选用合适的技术方案。

weixin_42526415的博客 404

RxJava 和 RxAndroid 三(生命周期控制和内存优化)

前言:对Rxjava、Rxandroid不了解的同学可以先看看RxJava 和 RxAndroidRxJava 和 RxAndroid 二(操作符的使用) RxJava使我们很方便的使用链式编程,代码看起来既简洁又优雅。但是RxJava使用起来也是有副作用的,使用越来越多的订阅,内存开销也会变得很大,稍不留神就会出现内存溢出的情况,这篇文章就是介绍Rxjava使用过程中应该注意的事项。 1、取消订阅subscription.unsubscribe(); package lib.com.myapp..

chuyouyinghe的专栏 723

std::map看来可以被淘汰了?可以用vector来替代,而且更好

vector的优势在于内存连续,可以先std::sort,然后std::lower_bound,或者std::binary_search。而std::map,insert的时候,需要new出内存。

tumu_C的博客 1019

存储关键技术·RAID技术·RAID2.0·华为RAID2.0+·华为服务器·云计算

一.RAID基本概念 常见的RAID级别组合RAID级别 二.RAID的数据组织形式 三.RAID的数据保护功能 方法一:镜像方法二:奇偶校验算法(XOR) 四.RAID热备和重构 1.热备(Hot Spare)的定义2.热备的分类3.热备的工作原理 五.RAID 2.0技术 1.RAID 2.02.RAID 2.0+3.华为RAID 2.0+ 六.RAID 2.0+块虚拟化技术 1.什么会出现RAID 2.0+技术?2.什么是RAID 2.0?3.RAID 2.0+的原理是什么?

qq_47480932的博客 3319

Activity与Fragment的通信

Bundle和接口(观察者模式)的实现方式

蔡林浩的博客 4638

RT-DETR算法优化改进:DCNv4更快收敛、更高速度、更高性能,效果秒杀DCNv3、DCNv2等 ,助力检测

DCNv4更快收敛、更高速度、更高性能,完美和RT-DETR结合,助力涨点

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1321

Activity 与 Fragment 之间常见的几种通信方式?

开始介绍方法之前,先借用之前lx36301766 写的答案里的一句话,我个人觉得写的很到位: 说到底就是两个普通的JAVA对象相互都持有对方的引用,直接回调就成,哪还需要什么别的通信方式,很简单的问题别搞复杂了 大家都知道java是面向对象的编程语言。只要拿到对象,想做什么操作其实很简单。好开始正文。 从两个方面开始说 Activity与Fragment通信 Fragemnt与Activit...

叫我帅阿蒙 1763

一种抑制undershoot/overshoot锐化算法介绍

一、USM 当增强图像的边缘、细节信息等高频信息时,图像的锐化视觉效果会得到较大提升。提高图像锐化的一种经典算法为非锐化掩码(UNsharp Masking)技术。该技术首先通过高通滤波并与缩放系数相乘,其结果再与原始图像相加,即可对高频信息进行增强。其主要的原理如下图所示: 其中,对图像进行高通滤波的另一种等效方法为:原始图像减去原始图像的低通滤波图像,其结果被称之为“掩码”。因此,上述的USM方法可以表示为: 原始图像减去原始图像低通滤波之后的图像得到掩码M。 2.掩...

大熊 4241

【异常】OpenClaw调用火山引擎大模型提示词 Agent failed before reply: All models failed (6): volcengine/kimi-k2-5-26

摘要: 本文针对OpenClaw调用火山引擎大模型服务时触发的全量熔断报错(All models failed)提供全链路排查方案。报错核心为服务熔断(cooldown)和模型不可用(model_not_found),主要源于账号权限、API凭证失效或模型标识错误。解决方案按优先级分步实施:1)校验账号状态与AK/SK有效性;2)核对官方模型标识;3)重启服务解除熔断;4)修复配置文件;5)通过原生API测试定位网络或服务端问题。日志分析(openclaw logs)可快速识别HTTP状态码(如401/40

奶爸的编程之路,也就一周冷个三天 836

观察者模式与Fragment间通信

前两天腾讯电话面试,被狠狠地虐了一把。本来以为还有周末两天可以好好准备,居然投完简历半个钟就打电话过来了,心塞。面试官提到一个问题,fragment间怎样实现通信。我回答通过Activity做中介。面试官要求用低耦合的方式,一时没想起。后来上网找了一下发现可以通过观察者模式来实现。虽然也是通过Activity做中介,但是不是直接在Fragment中通过操控另一个Fragment方式,而是在frag

ZionLife的博客 1221

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

安卓APP_ Fragment(2)—— Activity与Fragment的通信

这里写目录标题三、Fragment管理事务生命周期相关状态保存四、Fragment通信与动画Fragment与Activity通信Fragment之间的通信Fragment专场动画 三、Fragment管理 事务 生命周期 相关状态保存 四、Fragment通信与动画 Fragment与Activity通信 Fragment之间的通信 Fragment专场动画 ...

华天朱 819

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【Fragment 与 Activity 通信的方式】

Fragment 与 Activity 通信的的几种方式

春分之际的博客 1648

Android学习|Fragment——02.Avtivity与Fragment通信

Avtivity与Fragment通信 划分 Avtivity与Fragment通信 Fragment与Avtivity通信 Fragment与Fragment通信 1、Avtivity与Fragment通信 原生方案:Bundle类作为通信数据保存的载体 Bundle可保存string,byte等多种类型数据,而对于自定义的实体类Bean的保存,可使用putParcelable(string key,Parcelable value)实现 Parcelable 设计序列化之类的实现的 然后activ

weixin_52551903的博客 2396

Fragment与Activity的5种通信方式

本文介绍5种Fragment与Activity通信的方式:1)接口回调(官方推荐,解耦但需手动绑定);2)ViewModel+LiveData(生命周期感知,适合复杂数据共享);3)EventBus(简化通信但需第三方库);4)直接方法调用(简单但高耦合);5)Bundle传参(仅适合初始数据)。建议根据场景选择:简单交互用接口或ViewModel,跨组件通信用EventBus,避免直接调用以降低耦合。

时小雨的专栏 748

4月13日Activity发送信息给Fragment

Activity与Fragment通信

weixin_43653863的博客 3243

ViewModel - Activity 与 Fragment 通信 ViewModel 实现(ViewModel + 接口实现、ViewModel + LiveData 实现)

ViewModel - Activity 与 Fragment 通信 ViewModel 实现(ViewModel + 接口实现、ViewModel + LiveData 实现)

weixin_52173250的博客 1347

【Android】全球诡异降临:只有我能找到Fragment并与Activity进行数据传递

Override// 获取Fragment的argumentsif (bundle!= null) {// 使用获取到的数据方法这是一个静态工厂方法,用于创建 MyFragment的新实例,并传递数据。创建一个新的MyFragment实例。创建一个Bundle对象来保存参数数据。将参数存储到Bundle中(使用将Bundle设置为Fragment的arguments。返回配置好的Fragment实例。方法。

2301_79344902的博客 686

Activity与Fragment间通信_若雪似风_新浪博客

1. Handler方式 Handler 方式是了解了 Handler 的人最容易想到的,但是 Handler 不仅会增加各个模块之间的耦合性,而且只能单向通信,例如如果在 Activity 中实例化 Handler ,那么就只能由 Fragment 向 Activity 发送消息,而如果反过来 Activity 向 Fragment 发送消息则不易实现,既然不能双向,那么 Frag...

qq_18361681的博客 258
上一篇: 让x86的android模拟器能模拟arm架构系统
下一篇: 设计模式---观察者模式(C++实现)
zerokkqq
博客等级 码龄18年 310粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值