EventBus的使用

EventBus高级使用姿势 EventBus高级使用方法,如果这些你还不会,敢说你精通? 阅读详情

EventBus使用

在介绍EventBus之前先捋顺以下Android自带的应用内通信方式有哪些?

Android 应用内常用通信方式

1.使用handler进行线程间通信

handler是和Thread绑定的,主线程中创建Hander直接通过new Handler() 来创建即可。自定义线程中则还需要调用Looper.prepare Looper.loop来让Handler起作用,这里就不详细讲解原理及使用了,感兴趣的自己去探索一下。

Handler主要有两个作用,一个是线程间传递消息, 另一个则是post Runnable对象,让Runnable对象在Handler对应的那个线程里运行。
下面用最小代码简单介绍展示一下Handler在线程间传递消息的方式。

示例代码:
新建一个线程,延迟1s后通过主线程的Handler发送消息。
主线程的Handler收到消息后,打印log

public class MainActivity extends Activity{

    private  Handler mHandler;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=(Button) findViewById(R.id.button1);
        mHandler=new Handler(){

            @Override
            public void handleMessage(Message msg) {
                if(msg.what==0xff){
                    Log.e("what", "I got the Message");
                }
            }

        };

        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        mHandler.sendEmptyMessage(0xff);

                    }
                }).start();
            }
        });
    }

}

2.使用Interface定义回调,可以用在任意两个对象之间。比如Activity和Fragment通信

Android官方的Guides也是这么建议的
参考(http://developer.android.com/guide/components/fragments.html和http://developer.android.com/training/basics/fragments/communicating.html)

public static class FragmentA extends ListFragment {
    ...
    // Container Activity must implement this interface
    public interface OnArticleSelectedListener {
        public void onArticleSelected(Uri articleUri);
    }
    //在Fragment的onAttach方法中,绑定mListener(也就是需要实现了该接口的Activity)
     @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnArticleSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
        }
    }
    //当Fragment中的Item点击后,回调OnArticleSelectedListener的方法。Activity中实现的方法中即可做相应处理
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Append the clicked item's row ID with the content provider Uri
        Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
        // Send the event and Uri to the host activity
        mListener.onArticleSelected(noteUri);
    }

}

在Activity中需要实现FragmentA中的OnArticleSelectedListener接口
public class MainActivity extends Activity implements FragmentA.OnArticleSelectedListener{
@Override
public void onArticleSelected(Uri articleUri) {
//Do something to response the Item selection
}

}

使用Intent进行组件间的通信

通过Intent来比如启动Service,启动Activity,
通过Intent来发送Broadcast,然后注册一个BroadcastReceiver来接收并处理Intent. 这个部分比较基础,就不再赘述了。

EventBus进行应用内通信

如果想深入了解EventBus的实现原理,可以参考 EventBus 源码解析

简介

EventBus是Android端的一个订阅/发布的消息总线,用在应用程序内,组件之间,线程之间的通信,并且由于事件可以是任意类型的对象,所以使用起来更加的方便快捷。
角色:
Event:就是事件啦
Subscriber:订阅者,接收特定事件的对象,主要通过onEventXXX()回调接口接收
Publisher:发布者,post事件,通知订阅者

其他的先不多介绍了,后面慢慢展开。

使用过程

使用EventBus只有简单的4步
- 1 定义一个Event事件
- 2 注册一个订阅者
- 3 发布一个事件
- 4 接受这个事件

用代码实现这4步就是:
- 1 public class MyEvent()–可以是任意Object
- 2 EventBus.getDefault().register(this)—比如这时一个Activity,那就等于把Activity注册为一个订阅者
- 3 EventBus.getDefault().post(event)—随便哪个组件或者线程中发送出一个MyEvent的对象
- 4 public void onEvent(MyEvent event)–第2步中的Activity中的onEvent方法接收到该事件并处理。注意一定Event类型要对应。如果写成了onEvent(Object event),那就是post什么类型的Event都能接受了。

看起来的确很方便。下面给出一个Activity中的完整代码。也是比较简单,但是能够很清晰的看出EventBus是如何使用的。

示例代码
public class MainActivity extends Activity{

    private TextView textView;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=(Button) findViewById(R.id.button1);
        textView= (TextView) findViewById(R.id.textView1);
        //1.注册订阅者
        EventBus.getDefault().register(this);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
            //post事件
                EventBus.getDefault().post(new MyEvent());
            }
        });
    }
    //接收事件的回调
    public void onEvent(MyEvent event){
        Log.e("What", "[onEvent]My Thread is "+Thread.currentThread().getName());
    }

自定义的事件就是一个空的类,当然也可以加入不同的属性,方法。用来传递信息。

public class MyEvent {
}

点击按钮后可以看到TextView的内容已更改。

Log
03-29 18:56:22.738: E/What(17402): [onEvent]My Thread is main

onEventXXXX

onEvent函数一共有四种,前面的例子只用到一个onEvent。

函数名含义ThreadMode
onEvent事件处理在事件发送的那个线程执行PostThread
onEventMainThread事件在主线程-UI线程执行MainThread
onEventBackgroundThread事件在一个后台线程执行(就一个后台线程)BackgroundThread
onEventAsync事件会单独启动一个线程执行(每个事件都会启动一个线程)Async

其中前三个事件处理方式,都应该尽快完成。

onEventMainThread使用演示

onEventMainThread就是会放到主线程去执行的事件处理,一般在其中进行比如UI的更新的操作,比如TextView的更改。下面通过代码展示一下。一个自定义的线程发送该事件,Activity通过onEventMainThread接收到该事件,并更新UI.这个时候就不能使用onEvent了,因为根据上表所示,onEvent会放在发送事件的那个线程中去执行,其实不能进行UI更新操作的。

示例代码

public class MainActivity extends Activity{

    private TextView textView;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=(Button) findViewById(R.id.button1);
        textView= (TextView) findViewById(R.id.textView1);
        //1.注册订阅者
        EventBus.getDefault().register(this);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        EventBus.getDefault().post(new MyEvent());              
                    }
                }).start();
            }
        });
    }

    public void onEvent(MyEvent event){
        Log.e("What", "[onEvent]My Thread is "+Thread.currentThread().getName());
    }
    public void onEventMainThread(MyEvent event){
        Log.e("What", "[onEventMainThreadMy] Thread is "+Thread.currentThread().getName());
        textView.setText("onEventMainThread called");
    }

}

点击按钮后可以看到TextView的内容已更改。

Log

03-29 18:54:10.728: E/What(16993): [onEvent]My Thread is Thread-67572
03-29 18:54:10.778: E/What(16993): [onEventMainThreadMy] Thread is main

Sticky Event

Sticky Event是指我注册一个sticky的订阅,这样注册之前发送的sticky事件的最近的一个会保存在内存中,错过这个事件的发送的情况下,也可以通过getStickyEvent收到。

  • postSticky(event) :发送sticky的event
  • registerSticky(subscriber) :注册接收sticky事件的订阅者
  • getStickyEvent(Class

示例代码

public class MyEvent {
    public String what;

    public MyEvent(String what) {
        super();
        this.what = what;
    }

}
package com.example.eventbusdemo;

import de.greenrobot.event.EventBus;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    private TextView textView;
    private Button sendEvent;
    private Button quaryEvent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sendEvent = (Button) findViewById(R.id.button1);
        quaryEvent = (Button) findViewById(R.id.button2);
        textView = (TextView) findViewById(R.id.textView1);
        // 1.注册订阅者
        EventBus.getDefault().registerSticky(this);
        sendEvent.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // 点击按键发送5个Sticky event
                for (int i = 0; i < 5; i++) {
                    EventBus.getDefault().postSticky(
                            new MyEvent(String.valueOf(i)));
                }

            }
        });

        quaryEvent.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MyEvent lastEvent = EventBus.getDefault().getStickyEvent(
                        MyEvent.class);
                Log.e("What", "[quaryEvent] last Event is" + lastEvent.what);
            }
        });
    }

    public void onEvent(MyEvent event) {
        Log.e("What", "[onEvent] this Event is" + event.what);
    }
}

结果

点击sendEvent按钮:
Log

03-29 19:09:40.698: E/What(20520): [onEvent] this Event is0
03-29 19:09:40.698: E/What(20520): [onEvent] this Event is1
03-29 19:09:40.698: E/What(20520): [onEvent] this Event is2
03-29 19:09:40.698: E/What(20520): [onEvent] this Event is3
03-29 19:09:40.698: E/What(20520): [onEvent] this Event is4

点击quaryEvent按钮:
Log

03-29 19:12:31.578: E/What(20520): [quaryEvent] last Event is4

技巧

Event类一般都比较小,所以可以把它们都打包在一个Events类中。比如:

public class Events{
    public static class AbcEvent{
    }
    public static class XyzEvent{
    }
}
15、虚拟环境中的数据保护与恢复方案解析 本文深入解析了虚拟环境中两种重要的数据保护与恢复解决方案:RecoverPoint for Virtual Machines(RP4VM)在VxRail上的设计,以及Veeam Backup & Replication(VBR)与VxRail的集成方案。文章详细介绍了RP4VM的网络布局、故障转移场景及其相关问题,以及VBR的架构设计、备份与复制流程、许可证选项及其多平台支持特性。此外,还探讨了RP4VM与VBR结合使用的综合解决方案,以及未来数据保护领域的发展趋势,如智能化管理、云原生集成和零信任架构,为 阅读详情

相关推荐

Ansys Lumerical FDTD硬件配置避坑指南:从RTX 4090到A100的GPU选择实战

本文针对Ansys Lumerical FDTD仿真计算,深入分析了从消费级RTX 4090到专业级A100的GPU硬件配置选择。文章指出,选择的关键在于显存容量能否容纳仿真模型,并对比了二者在显存、双精度算力及多卡扩展性上的核心差异,为不同预算和仿真规模的用户提供了实战避坑指南与配置建议。

weixin_29196891的博客 271

有关EventBus的一些问答

以下结论基于EventBus2.4.0问: 注册EventBus后,EventBus怎么保存我们的注册信息,这里的注册信息包括我们是在哪个Activity或Fragment中注册的,注册的事件,以及接收事件时处理的方法?答:EventBus通过反射找到我们的事件类型和接收事件处理的方法,以及处理事件时的线程模式,封装到一个叫SubscriberMethod的类中,然后把SubscriberMetho

su_buju的博客 435

IDEA+JRebel实现SpringBoot+MyBatis Plus项目热部署全攻略(含XML热更新实战)

本文详细介绍了如何在IDEA中使用JRebel为SpringBoot与MyBatis Plus项目配置高效的热部署方案。通过安装激活JRebel插件并配置关键扩展,重点解决了MyBatis XML映射文件修改后无法即时生效的痛点,实现了Java代码与XML文件的秒级热更新,从而彻底摆脱频繁重启应用的开发困境,大幅提升编码与调试效率。

weixin_28831341的博客 471

【Jetpack篇】LiveData取代EventBus?LiveData的通信原理和粘性事件刨析

LiveData是一个可以在给定生命周期内观察到的数据持有者类。一个观察者可以与一个LifecycleOwner成对地添加,并且只有当配对的LifecycleOwner处于活动状态时,这个观察者才会收到数据变动的通知。 LiveData-ViewModel-Repository 以下是LiveData结合ViewModel请求数据的伪代码,这也是JetPack中最常见的一种写法。 ViewModel层:继承ViewModel并创建LiveData,通过postValue将数据发射给UI。 class E.

二气乖张的博客 662

【TiktokAPI】Tiktok直播API与实时互动功能开发完全指南

Tiktok直播API允许开发者创建、管理直播,并实现各种互动功能。/*** 获取Tiktok直播API访问令牌* @param {string} client_id - 应用ID* @param {string} client_secret - 应用密钥* @param {string} code - 授权码* @param {string} redirect_uri - 重定向URI* @returns {Promise<object>} 访问令牌响应*/try {}),

Mageia的专栏 3187

TOEIC托业词汇汇总(完整版)

1.appointment 约会,约定2.attendance 出席人数;出席3.cabinet 橱柜4.calendar 日历;月历;行事历5.clerk 办事员,书记6.directory 人名住址薄7.duplicte 复制;副本8.filing 归档9.in-tray 待处理文件盒10.monitor 检测;监视;追踪11.out-tray 已处理文件盒12.partition 分隔;分隔物(如墙壁等)13.postage 邮费。

weixin_39676449的博客 1万+

EventBus、Rxbus、LiveBusEvent

EventBus EventBus2.x使用的是运行时注解,它采用了反射的方式对整个注册的类的所有方法进行扫描来完成注册,因而会对性能有一定影响。 EventBus3.x使用的是编译时注解,Java文件会编译成.class文件,再对class文件进行打包等一系列处理。在编译成.class文件时,EventBus会使用EventBusAnnotationProcessor注解处理器读取@Subscribe()注解并解析、处理其中的信息,然后生成Java类来保存所有订阅者的订阅信息。这样就创建出了对文件或类的

hsw 1013

rk3576 点亮 LCD(mipi)

瑞芯微 RK3576 是一款面向中高端 AIoT 市场的 SoC,其 MIPI DSI (Display Serial Interface) 接口在性能和灵活性上相比前代(如 RK3399/RK3568)有显著提升,特别是在物理层协议的支持上更加现代化。相比RK3399 RK3568的mipi 接口少了 8lane,但是RK3576 MIPI DSI 增加更低功耗的 C-PHY。

weixin_35723192的博客 362

android开发:eventBus引发的内存泄漏问题

讲解之前我们先讨论一个问题:activity非正常结束生命周期(发生异常或系统内存不足强制回收)会不会走onDestroy()方法? public class Main2Activity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { ...

一个程序员-二白的博客 2608

基于Python的CT骨料图像分割与STL批量导出完整指南

本文介绍了一套完整的Python解决方案,用于CT骨料图像的分割与STL导出。针对CT图像中颗粒粘连、噪声伪影等技术难点,提出基于分水岭算法的分割策略,结合距离变换与标记控制实现颗粒分离。内容包括环境配置、数据读取与预处理、Otsu阈值分割、分水岭算法实现、表面提取与STL导出等关键步骤。教程提供详细代码及解释,帮助读者从CT体数据出发,最终生成每个颗粒的三维网格文件,便于后续定量分析和数值模拟。

huanghm88的专栏 235

FAST-LIVO2 源码精读(十六):接入自定义传感器——多雷达适配与内外参标定

本文是「FAST-LIVO2 激光-惯性-视觉里程计源码精读」专栏第十六篇。上一篇拆解了中每个关键参数的物理含义与调参路径,并反复强调外参RclPcl与时间偏移配错即全局失效;本篇承接这一悬念,回答更前置的工程问题——如何把 FAST-LIVO2 接到一套全新硬件上:新雷达如何通过的类型分支适配、相机内参与畸变模型如何配置、两组外参与时间偏移如何标定出来并填入 YAML,最后给出一份落地检查清单。

PX4-SLAM-PNC 197

android跨进程订阅消息,Android 消息总线 LiveEventBus

## LiveEventBusLiveEventBus是一款Android消息总线,基于LiveData,具有生命周期感知能力,支持Sticky,支持AndroidX,支持跨进程,支持跨APP- 生命周期感知,消息随时订阅,自动取消订阅- 支持Sticky粘性消息- 支持AndroidX- 支持跨进程通信- 支持跨APP通信- 支持设置LifecycleObserver(如Activity)接收消...

weixin_33514582的博客 853

Qt C++ 串口调试助手

1. **串口配置**:支持自动检测可用串口,可配置波特率(9600~921600)、数据位(5~8)、校验位(无/奇/偶/标记/空格)、停止位(1/1.5/2)。- HEX 模式发送时,输入格式需为十六进制字符(0-9、A-F),可带空格(如 `01 A3 FF`)或不带空格(如 `01A3FF`)。// 发送模式:true=HEX,false=ASCII。// 字符串转HEX字节数组。ui->parity->addItems({"无", "奇校验", "偶校验", "标记校验", "空格校验"});

寒寒豆豆软件公司的博客 144

Android EventBus的使用

参考文章:https://blog.csdn.net/bskfnvjtlyzmv867/article/details/71480647 使用场景:应用程序内各组件间、组件与后台线程间的通信。 比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。 EventBus的三要素 : ...

NewActivity的博客 1万+

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

EventBus使用

#第一步 引入类库 implementation 'org.greenrobot:eventbus:3.1.1' #第二步 定义事件 public class MessageEvent { public final String message; public MessageEvent(String message) { this.message = mes...

weixin_43966265的博客 186

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

安卓Eventbus的使用

EventBus可以代替Android传统的Intent,Handler,Broadcast或接口函数,在Fragment,Activity,Service线程之间传递数据,使用简单,代码简洁,下面将介绍如果集成使用。 第一步添加依赖: implementation 'org.greenrobot:eventbus:3.0.0' 第二步注册: onCreate方法中注册 if (!EventBu...

qq_36356379的博客 1702

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

安卓EventBus使用方法,eventbus举例

原帖: 跳转 1、EventBus 简介 EventBus是一种用于Android的事件发布-订阅总线,由GreenRobot开发,Gihub地址是:EventBus。它简化了应用程序内各个组件之间进行通信的复杂度,尤其是碎片之间进行通信的问题,可以避免由于使用广播通信而带来的诸多不便。 1.1 三个角色 Event:事件,它可以是任意类型,EventBus会根据事件类型进行全局的通知。 Subscriber:事件订阅者,在EventBus 3.0之前我们必须定义以onEvent开头的那几个方法,分别

ruiruiddd的博客 2304

EventBus使用详解(一)——初步使用EventBus

前言:EventBus是上周项目中用到的,网上的文章大都一样,或者过时,有用的没几篇,经过琢磨,请教他人,也终于弄清楚点眉目,记录下来分享给大家。 相关文章: 1、《EventBus使用详解(一)——初步使用EventBus》 2、《EventBus使用详解(二)——EventBus使用进阶》 一、概述 EventBus是一款针对Android优化的发布/订阅事件总线。主要功...

启舰 43万+

EventBus使用详解

创建一个简单的Java类作为事件对象,该类通常只包含要传递的数据和相应的getter/setter方法。

卡拉米 1725

【Android】EventBus 的使用

Android 事件总线 EventBus 的使用

LiuYaoheng的博客 1202

Android中EventBus的简单使用

Android系统内置的事件通讯存在缺点:Android系统中的事件通信则是 handler (消息机制) 和 BroadCastReceiver (广播机制), 通过它们可以实现组件之间的事件通讯。缺点在于,代码量多、组件之易产生藕合引用。

Sean_Word的博客 2400

Dialog 中 使用 EventBus 问题

使用中遇到 首次使用dialog 进行数据发送 ,EventBus 还有效果 ,但是当Dismiss 操作后 ,再次showdialog EventBus 事件传达就无法实现 我注册在 在onCreate() 销毁是在 Stop() 但是Dialog仅在在第一次启动时候会执行onCreate()方法(之后无论该Dialog执行Dismiss(),cancel(),stop(),Dialog...

u013297881的专栏 4245

eventbus使用_Android EventBus框架的使用介绍

EventBus 是Android和Java数据通信的一个简捷框架,在Android中,主要用于线程直接的通信以及Activity,Fragment等之间的数据交互等官方介绍简化组件之间的通信,解耦事件发送方和接收方,可以很好地处理Activity、Fragment和后台线程直接的数据交互,避免复杂且容易出错的依赖项和生命周期问题使您的代码更简单更快捷小(60k 的jar包)被安装在十亿以上的应用...

weixin_39624705的博客 109
上一篇: Android网络图片加载优化
下一篇: Mac 使用Source Insight (借助Wine For Mac)
crazy_chen
博客等级 码龄17年 21粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值