zoukankan      html  css  js  c++  java
  • EventBus (四) Sticky事件

    什么是Sticky事件?

    关于Sticky事件有的同学可能不是很熟悉,Sticky的意思是粘性的。在Android开 发中,Sticky事件只指事件消费者在事件发布之后才注册的也能接收到该事件的特殊类型。Android中就有这样的实例,也就是Sticky Broadcast,即粘性广播。正常情况下如果发送者发送了某个广播,而接收者在这个广播发送后才注册自己的Receiver,这时接收者便无法接收到 刚才的广播,为此Android引入了StickyBroadcast,在广播发送结束后会保存刚刚发送的广播(Intent),这样当接收者注册完 Receiver后就可以接收到刚才已经发布的广播。这就使得我们可以预先处理一些事件,让有消费者时再把这些事件投递给消费者。

    AndroidEventBus也提供了这样的功能,有所不同是AndroidEventBus会存储所有的Sticky事件,如果某个事件在不需 要再存储则需要手动进行移除。用户通过Sticky的形式发布事件,而消费者也需要通过Sticky的形式进行注册,当然这种注册除了可以接收 Sticky事件之外和常规的注册功能是一样的,其他类型的事件也会被正常处理。发布、接收Sticky事件的步骤有如下几步 :

    1、发布Sticky事件;

    EventBus.getDefault().postSticky("hello");

    2、 某个时刻订阅者以Sticky的形式注册

    
    public class MyReceiver {
        public MyReceiver() {
            EventBus.getDefault().registerSticky(this);
        }
    
        @Subscriber
        private void onStickyEvent(String info) {
            System.out.println("接收到事件 : " + info);
        }
    
    }

    当在某个时刻构造MyReceiver时就会将MyReceiver对象以Sticky的形式注册到EventBus中,此时先前发布的”hello”事件就会被MyReceiver对象接收到,因此就会执行onStickyEvent函数,在该函数中实现具体的逻辑即可。当然,不要忘了在某个时刻将MyReceiver注销,以弱引用的形式持有订阅者的功能还没有完成呐!整个过程就这样结束了~

    Sticky事件的运用场景

    上文中我们简单讲述了Sticky事件的基本使用步骤,这里我们以一个具体的示例来看看Sticky事件在开发中的使用场景。

    在开发过程中,我们经常需要在Activity之间传值,我们的做法就是将数据塞到Intent中,并且为每个数据设置一个key。当我们传递的数 据是一个实体类时,我们的这个类还需要实现序列化接口,比如Parcelable或者Serializable。例如我们需要将一个用户对象传递到用户个 人信息展示页面。我们的常规做法是这样的:

    User.java类 :

    // 实体类实现序列化
    public class User implements Parcelable {
            String name ;
            String phoneNum;
            // 其他字段省略
    
            public User(String aName) {
                name = aName ;
            }
    
            public User(Parcel in) {
                super(in);
                name = in.readString();
                phoneNum = in.readString();
            }
           // 代码省略
    
            @Override
            public void writeToParcel(Parcel dest, int flags) {
                dest.writeString(name);
                dest.writeString(phoneNum);
            }
    
            public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
    
            @Override
            public User createFromParcel(Parcel source) {
                return new User(source);
            }
    
            @Override
            public User[] newArray(int size) {
                return new User[size];
            }
        };
     }

    然后我们要在某个Activity中将这个用户数据传递给个人信息界面ProfileActivity。代码如下 :

    public class MainActivity extends Activity {
    
        // 某个点击事件
        @Override 
        public void onClick(View v) {
            User aUser = new User("Mr.Simple");
            aUser.phoneNum = "123456";
            // 其他数据
    
            Intent intent = new Intent(this, ProfileActivity.class);
            intent.putParcelable("user", aUser);
            startActivity(intent);
        }
    }

    在某个点击事件的处理函数中我们通过Intent将数据传递给ProfileActivity。我们再看看ProfileActivity从Intent中取出数据的代码。

    public class ProfileActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_profile);
            // 从Bundle中获取数据
            Bundle extraBundle = getIntent().getExtras();
            if (extraBundle != null) {
                User user = extraBundle.getParcelable("user");
            }
        }
    }

    OK,至此整个过程才算结束了。

    大哥,我只是需要传个数据啊!何苦啊!
    这种方式产生了很多的样板代码,也让逻辑变得更复杂,容易出错。我们再看看使用Sticky事件的实现方式。

    User.java类 :

    // 实体类实现序列化
    public class User  {
            String name ;
            String phoneNum;
            // 其他字段省略
    
            public User(String aName) {
                name = aName ;
            }
    
            // 代码省略
     }

    首先User类不需要实现序列化接口,避免了那些样板代码。然后在MainActivity中直接将User对象作为Sticky事件发布即可。

    public class MainActivity extends Activity {
    
        // 某个点击事件
        @Override 
        public void onClick(View v) {
            User aUser = new User("Mr.Simple");
            aUser.phoneNum = "123456";
            // 其他数据
            // 发布Sticky事件
            EventBus.getDefault().postSticky(aUser);
            // 跳转到ProfileActivity页面
            Intent intent = new Intent(this, ProfileActivity.class);
            startActivity(intent);
        }
    }

    最后我们看看ProfileActivity如何接收数据。

    public class ProfileActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_profile);
    
            // 以Sticky的形式注册
            EventBus.getDefault().registerSticky(this);
        }
    
        @Subscriber
        private void onStickyEvent(User info){
             // 这里实现你的逻辑即可, info即为传递过来的User对象
        }
    
    }

    在ProfileActivity中我们将ProfileActivity自身作为订阅者注册到总线当中,此时ProfileActivity就会 接收到上面发布的Sticky事件,这个事件对象就是User对象。此时就会触发ProfileActivity 中的receiveUser函数,info参数就是Sticky事件的那个用户信息对象,在receiveUser中实现自己的逻辑即可。

    是的!我们并没有在onDestory中对订阅者进行注销,也就是没有调用EventBus的unregister()函数,这就是最新版的特性之一,也是目前唯一不需要手动注销的事件总线库。

    借鉴:http://blog.csdn.net/bboyfeiyu/article/details/46116357

  • 相关阅读:
    安防视频云服务EasyCVR视频上云网关如何通过wireshark将发送的rtp流数据保存成文件?
    安防视频监控系统视频上云解决方案EasyCVR语音转发功能音频数据打包发送流程介绍
    安防视频监控系统视频上云解决方案EasyCVR音频基础知识介绍
    如何通过RTSP协议视频平台EasyNVR建立一套外网可访问的4S店远程监控系统?
    IP摄像机RTSP协议视频平台EasyNVR点击程序启动后闪退问题排查及解决
    5G时代RTC技术是直播互动的最终选择,EasyRTC视频会议系统将赋能VR/电商直播等更多新场景
    视频会议软件EasyRTC-SFU之mediasoup-demo在 Windows上的编译安装
    视频会议软件/音视频通话软件EasyRTC-SFU开发中如何使用TortoiseGit将代码推送到两个代码仓库?
    SFU架构的云视频会议系统如何取代硬件视频会议系统,成为5G时代的视频会议新宠?
    云架构视频会议系统EasyRTC企业远程会议MCU版与SFU版在行业应用场景上有什么区别?
  • 原文地址:https://www.cnblogs.com/ldq2016/p/5387444.html
Copyright © 2011-2022 走看看