EventBus3使用实战(二)

EventBus3使用实战(二)

EventBus3的使用实战(一)

Sticky Event使用

自己写了一个小例子,两个activity,通过EventBus来传递事件,布局比较简单,代码不贴出来了,
MainActivity:
EventBus3使用实战(二)_第1张图片

SecondActivity:
EventBus3使用实战(二)_第2张图片

MainACtivity:

public class MainActivity extends FragmentActivity {
@BindView(R.id.title_tv)
    TextView mTextView;

        @OnClick(R.id.child_thread_btn)
        public void onChildThreadClick(){

            new Thread() {
                @Override
                public void run() {
                    // EventBus.getDefault().post("hhh");

     EventBus.getDefault().postSticky("from MainActivity--child thread post sticky event");

                }
            }.start();

        }

        @OnClick(R.id.main_thread_btn)
        public void onMainThreadClick(){
            EventBus.getDefault().postSticky("from MainActivity--main thread post sticky event");

        }


        @OnClick(R.id.next_activity_btn)
                public void onNextActivityClick(){
            startActivity(new Intent(MainActivity.this, SecondActivity.class));

        }



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        mTextView.setText("sdongwan");
    }

    @Override
    protected void onStart() {
        super.onStart();
       EventBus.getDefault().register(this);
    }


    @Override
    protected void onStop() {
        super.onStop();

        EventBus.getDefault().unregister(this);

    }


    @Subscribe(sticky = true)
    public void onHandleStickyEvent(String str) {
        Log.e("thread", "onHandleStickyEvent----MainActivity: main " + str);


    }


}

SecondActivity:

public class SecondActivity extends AppCompatActivity {

    @OnClick(R.id.post_sticky_btn)
   public void onStickyEventClick(){
        EventBus.getDefault().postSticky("from SecondActivity--post sticky event");
    }

    @OnClick(R.id.post_common_btn)
    public void onCommonEventClick(){
        EventBus.getDefault().post("from SecondActivity--post common event");

    }


    @OnClick(R.id.last_activity_btn)
    public void onLastClick(){
        finish();
    }


    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }


    @Override
    protected void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        ButterKnife.bind(this);

    }

    @Subscribe(sticky = true)
    public void onHandleStickyEvent(String str) {
        Log.e("thread", "onHandleStickyEvent------SecondActivity:   " + str);

    }

}
  • 点击从子线程发出粘性事件,并跳到SecondActivity界面,打印的日志如图:

这里写图片描述
可以看见MainActivity中onHandleStickyEvent(String str)和SecondActivity中onHandleStickyEvent(String str)事件处理方法都获得了粘性事件;此时,从MainActivity和SecondActivity重复跳动多次,日志会打印出多行事件处理信息,如图:
这里写图片描述

因为两个Activity间重复跳动多次,导致EventBus.getDefault().register(this)注册多次,每注册一次,EventBus3就会把粘性事件发给事件处理方法,导致重复打印出多行日志;

  • 点击SecondActivity中的发送普通事件,两个activity来回跳动,发现日志就打印一次,如图:

这里写图片描述

因为post的是普通事件,没有滞留,事件处理日志只打印一次,MainActivity中收不到普通事件;
这里我们post出的是普通事件,SecondActivity中事件处理机制上加了@Subscribe(sticky = true),也是可以处理普通事件,只是在我们来回切换activity中,日志也只打印一条,因为普通事件没有滞留,重新EventBus.getDefault().register(this),也不会再收到事件;
当然我们在SecondActivity中发送滞留事件,MainActivity也是可以收到的;

提示:EventBus.getDefault().register(this),这句代码的意义是在当前的activity中检索可以响应事件处理(订阅者)的代码,找到类型匹配的事件处理类型,则调用事件处理代码,如果我们在这个例子中,不在MainActivity中注册EventBus,那么我们在MainActivity中post粘性事件,MainActivity中的订阅者就不会被调用;

手动取消粘性事件

在上面的例子中,一旦我们post出粘性事件,来回切换activity,都会调用事件处理方法,如果我们一直切换,就会一直调用,这时我们要看看取消事件;
把上面的MainActivity中订阅者事件处理添加几行代码:

@Subscribe(sticky = true)
public void onHandleStickyEvent(String str) {
    Log.e("thread", "onHandleStickyEvent----MainActivity: main " + str);

    String stickyEvent = EventBus.getDefault().getStickyEvent(String.class);
    if(stickyEvent != null) {
        EventBus.getDefault().removeStickyEvent(stickyEvent);

    }

添加上面取消粘性事件代码后。切换到SecondActivity中,发现不会调用事件处理代码,粘性事件被取消了;
这里写图片描述

使用AsyncExecutor

在MainActivity onCreate方法中添加如下代码,自己手动抛出一个异常:

AsyncExecutor.create().execute(
            new AsyncExecutor.RunnableEx() {
                @Override
                public void run() throws LoginException {
                    // No need to catch any Exception (here: LoginException)

                    EventBus.getDefault().post(new MyEvent());
                    throw new LoginException();
                }
            }
    );

添加事件处理代码:

@Subscribe
   public void onHandleStickyEvent(MyEvent str) {
       Log.e("thread", "onHandleStickyEvent----MainActivity: main " + str);


   }


   @Subscribe(threadMode = ThreadMode.MAIN)
   public void handleFailureEvent(ThrowableFailureEvent event) {
       // do something

       Log.e("thread", "handleFailureEvent: "+event.toString() );
   }

运行打印的log如图:

这里写图片描述

可以看到RunnableEx可以帮助我们处理异常,把异常包裹成ThrowableFailureEvent中,然后post出去,我们可以在订阅者中写相应的异常处理逻辑;

使用索引(Subscriber Index)

使用android-apt生成索引

在project下的build.gradle添加下面代码

buildscript {
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

在app下的build.gradle添加下面代码:

apply plugin: 'com.neenbedankt.android-apt'

dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}

apt {
    arguments {
        eventBusIndex ""study.sdw.com.study.myindex(这个根据自己的包名来写,myindex是索引类)""
    }
}

点击rebuild,重新build一下,没有错误的话,就可以看到生成的索引类,索引类是在build过程生成的:
EventBus3使用实战(二)_第3张图片

点击查看生成的代码:


/** This class is generated by EventBus, do not edit. */
public class myindex implements SubscriberInfoIndex {
    private static final Map, SubscriberInfo> SUBSCRIBER_INDEX;

    static {
        SUBSCRIBER_INDEX = new HashMap, SubscriberInfo>();

        putIndex(new SimpleSubscriberInfo(SecondActivity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onHandleStickyEvent", String.class, ThreadMode.POSTING, 0, true),
        }));

        putIndex(new SimpleSubscriberInfo(MainActivity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onHandleStickyEvent", MyEvent.class),
            new SubscriberMethodInfo("handleFailureEvent", org.greenrobot.eventbus.util.ThrowableFailureEvent.class,
                    ThreadMode.MAIN),
        }));

    }

    private static void putIndex(SubscriberInfo info) {
        SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);
    }

    @Override
    public SubscriberInfo getSubscriberInfo(Class subscriberClass) {
        SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);
        if (info != null) {
            return info;
        } else {
            return null;
        }
    }
}

代码里通过索引来保存SubscriberInfo,这样我们就可以在代码配置默认的实例,让它使用索引:

 EventBus.builder().addIndex(new myindex()).installDefaultEventBus();

官方说使用索引可以性能提高几倍:
EventBus3使用实战(二)_第4张图片

你可能感兴趣的:(android工具库)