zoukankan      html  css  js  c++  java
  • <Android>greenrobot-EventBus,guava-Event Bus的异步实现

    刚開始是从otto入手,可是otto不支持异步运行。所以后来才開始研究了Event Bus。关于Event Bus,先前搜索的时候,看到网上的实例,非常碎,并且非常多都是一样的内容,代码看下来基本上是分2套写法。这就带来了疑问。后来再细致浏览原先的帖子发现了Event Bus有2套源代码。一个是greenrobot的Event Bus,一个是google的guava Event Bus。今天谈论的并非2套Event Bus的原理以及不同之处,这些内容基本在网上都有參考,临时不在这里累赘介绍了。等有时间深入研究的时候能够再写一遍具体的Event Bus的介绍。这次基本的是介绍2套Event Bus的异步实现,网上中文页面搜索基本非常少有Event Bus异步的介绍,有的话也是非常easy的代码实例,并且仅仅有抛事件的代码,尝试过后都是失败的,最后都是在外文站点上搜索到了关键的代码,好了不废话。直接上代码。

    首先介绍的是greenrobot Event Bus


    package com.benny.test;


    import java.util.ArrayList;
    import java.util.List;


    import android.app.Activity;
    import android.graphics.Color;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.LinearLayout;
    import android.widget.LinearLayout.LayoutParams;
    import android.widget.TextView;
    import de.greenrobot.event.EventBus;


    public class MyEventByusTestActivity extends Activity implements OnClickListener {

    private EventBus eventBus = EventBus.getDefault();
    private LinearLayout viewGroup;

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            viewGroup = (LinearLayout)findViewById(R.id.main_layout);

    // button设置响应接口
            findViewById(R.id.postthread).setOnClickListener(this);
            findViewById(R.id.mainthread).setOnClickListener(this);
            findViewById(R.id.backgroundthread).setOnClickListener(this);
            findViewById(R.id.async).setOnClickListener(this);
        }


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

    // 注销事件响应
    eventBus.unregister(this);
    }


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

    // 注冊事件响应
    eventBus.register(this);
    }


    @Override
    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.postthread:

    // 抛出PostThread模式的LoadButtonEvent事件
    eventBus.post(loadButtonList("postthread", 30));
    break;
    case R.id.mainthread:

    // 抛出MainThread模式的LoadLineEvent事件
    eventBus.post(loadLineList(20));
    break;
    case R.id.backgroundthread:

    // 抛出BackgroundThread模式的LoadNoneEvent事件
    eventBus.post(new LoadNoneEvent());
    break;
    case R.id.async:

    // 抛出Async模式的LoadAsyEvent事件
    eventBus.post(new LoadAsyEvent());
    break;
    default:
    break;
    }
    }
        
    public LoadEvent loadTextList(String str, int num) {
    ArrayList<TextView> list = new ArrayList<TextView>(num);
    for (int i = 0; i < num; i++) {
    TextView textView = new TextView(this);
    textView.setText(str + i);
    list.add(textView);
    }
    return new LoadEvent(list);
    }

    public LoadLineEvent loadLineList(int num) {
    ArrayList<View> list = new ArrayList<View>();
    for (int i = 0; i < num; i++) {
    View view = new View(this);
    view.setBackgroundColor(Color.BLUE);
    list.add(view);
    }
    return new LoadLineEvent(list);
    }

    public LoadButtonEvent loadButtonList(String str, int num) {
    ArrayList<Button> list = new ArrayList<Button>();
    for (int i = 0; i < num; i++) {
    Button button = new Button(this);
    button.setText(str + i);
    list.add(button);
    }
    return new LoadButtonEvent(list);
    }

    // 以PostThread的方式接受LoadButtonEvent事件
    public void onEvent(LoadButtonEvent event) {
    Log.d("EventBus", "load post thread");
    addButtonViews(event);
    }

    // 以MainThread的方式接受LoadLineEvent事件
    public void onEventMainThread(LoadLineEvent event) {
    Log.d("EventBus", "load main thread");
    addLineViews(event);
    }

    // BackgroundThread的方式接受LoadNoneEvent事件
    public void onEventBackgroundThread(LoadNoneEvent event) {
    Log.d("EventBus", "load background thread");
    LoadEvent loadE = loadTextList("backgroundthread", 500);

    // 抛出MainThread模式的LoadEvent事件用来更新界面
    eventBus.post(loadE);
    }

    // 以Async的方式接受LoadAsyEvent事件
    public void onEventAsync(LoadAsyEvent event) {
    Log.d("EventBus", "load async");
    LoadEvent loadE = loadTextList("async", 1000);

    // 抛出MainThread模式的LoadEvent事件用来更新界面
    eventBus.post(loadE);
    }

    // 以MainThread的方式接受LoadEvent事件
    public void onEventMainThread(LoadEvent event) {
    addTextViews(event);
    }

    private void addLineViews(LoadLineEvent event) {
    viewGroup.removeAllViews();
    for (View view : event.list) {
    LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 20);
    viewGroup.addView(view, param);
    }
    }

    private void addButtonViews(LoadButtonEvent event) {
    viewGroup.removeAllViews();
    for (Button button : event.list) {
    LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    viewGroup.addView(button, param);
    }
    }

    private void addTextViews(LoadEvent event) {
    viewGroup.removeAllViews();
    for (TextView view : event.list) {
    LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    viewGroup.addView(view, param);
    }
    }

    class LoadEvent {

    List<TextView> list;

    public LoadEvent(List<TextView> list) {
    this.list = list;
    }
    }

    class LoadLineEvent {

    List<View> list;

    public LoadLineEvent (List<View> list) {
    this.list = list;
    }
    }

    class LoadButtonEvent {

    List<Button> list;

    public LoadButtonEvent(List<Button> list) {
    this.list = list;
    }
    }

    class LoadNoneEvent {

    }

    class LoadAsyEvent {

    }
    }

    界面事实上非常easy。四个button,分别为R.id.postthread,R.id.mainthread,R.id.backgroundthread,R.id.async。这个是分别针对Event Bus中ThreadMode的四种模式:PostThread,MainThread,BackgroundThread,Async。

    PostThread —— 直接将事件抛在当前的线程中。

    MainThread —— 将事件抛在主线程中(UI线程)。

    BackgroundThread —— 将事件抛在新的线程中。

    Async —— 将事件抛在异步线程中。


    viewGroup是一个在ScrollView以下的LinearLayout布局。


    greenrobot Event Bus,其固定的接受事件代码是

    public void onEvent(AnyEvent event) -- PostThread

    public void onEventMainThread(AnyEvent event) -- MainThread

    public void onEventBackgroundThread(AnyEvent event) -- BackgroundThread

    public void onEventAsync(AnyEvent event) -- Async

    事实上另一种方法,能够直接定义事件接受的方法。

    可查看EventBus中的代码 public void register(Object subscriber, String methodName, Class<?> eventType, Class<?>... moreEventTypes)

    methodName -- 能够是自定义的方法名,能够全然代替"onEvent",至于4种模式相同能够区分,methodName仅仅须要前缀。譬如传递的參数是loadEvent。而代码中的方法是public void loadEventAsync(AnyEvent event),则表示是通过Async抛出的事件。以此类推。

    Class<?> eventType, Class<?>... moreEventTypes -- 是于事件相关的一些參数。

    也能够通过阅读EventBus的源代码来获取很多其它的信息。

    在BackgroundThread,Async模式中,最后假设要刷新界面的话。他们还是须要在以MainThread的模式抛出刷新界面的事件。

    greenrobot Event Bus下载地址:https://github.com/greenrobot/EventBus


    接着介绍guava Event Bus。

    package com.benny.test;


    import java.util.concurrent.Executor;


    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Looper;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.LinearLayout;
    import android.widget.LinearLayout.LayoutParams;
    import android.widget.TextView;


    import com.google.common.eventbus.AsyncEventBus;
    import com.google.common.eventbus.EventBus;
    import com.google.common.eventbus.Subscribe;


    public class GuavaEventBusDemoActivity extends Activity implements OnClickListener {

    // 创建异步的EventBus
    private EventBus asyBus = new AsyncEventBus(new Executor() {

    private Handler mHandler;
     

    // 实现异步机制的事件处理
    @Override
    public void execute(Runnable command) {
    if (mHandler == null) {
    mHandler = new Handler(Looper.getMainLooper());
    }
    mHandler.post(command);
    }

    });
    private EventBus bus = new EventBus();
    private LinearLayout viewGroup;


        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            viewGroup = (LinearLayout)findViewById(R.id.main_layout);
            findViewById(R.id.postthread).setOnClickListener(this);
            findViewById(R.id.mainthread).setOnClickListener(this);
            findViewById(R.id.backgroundthread).setOnClickListener(this);
            findViewById(R.id.async).setOnClickListener(this);
        }
        
    @Override
    protected void onPause() {
    super.onPause();

    // 注销事件订阅者
    bus.unregister(this);
    asyBus.unregister(this);
    }


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

    // 注冊事件订阅者
    bus.register(this);
    asyBus.register(this);
    }




    @Override
    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.postthread:
    break;
    case R.id.mainthread:

    // 主线程抛LoadButtonEvent事件
    bus.post(new LoadButtonEvent("main thread", 100));
    break;
    case R.id.backgroundthread:
    break;
    case R.id.async:

    // 异步线程抛LoadTextEvent事件
    asyBus.post(new LoadTextEvent("async", 1000));
    break;
    default:
    break;
    }
    }

    // 订阅LoadButtonEvent事件处理
    @Subscribe
    public void loadButtonList(LoadButtonEvent event) {
    Log.d("Guava", "ButtonEvent" + event);
    viewGroup.removeAllViews();
    for (int i = 0; i < event.num; i++) {
    Button button = new Button(this);
    button.setText(event.str + i);
    LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    viewGroup.addView(button, param);
    }
    }

    // 订阅LoadTextEvent事件处理
    @Subscribe
    public void loadTextListAsync(LoadTextEvent event) {
    Log.d("Guava", "TextEvent=" + event.str);
    viewGroup.removeAllViews();
    for (int i = 0; i < event.num; i++) {
    TextView textView = new TextView(this);
    textView.setText(event.str + i);
    LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    viewGroup.addView(textView, param);
    }
    }

    class LoadButtonEvent {
    String str;
    int num;

    public LoadButtonEvent(String str, int num) {
    this.str = str;
    this.num = num;
    }
    }

    class LoadTextEvent {
    String str;
    int num;

    public LoadTextEvent(String str, int num) {
    this.str = str;
    this.num = num;
    }
    }

    }

    界面跟上一个实例是一样的,只是仅仅用到了2个button。MainThread和Asyncbutton。viewGroup是一个在ScrollView以下的LinearLayout布局。

    异步的关键就在于

    private EventBus asyBus = new AsyncEventBus(new Executor() {

    private Handler mHandler;
     

    // 实现异步机制的事件处理
    @Override
    public void execute(Runnable command) {
    if (mHandler == null) {
    mHandler = new Handler(Looper.getMainLooper());
    }
    mHandler.post(command);
    }

    });

    这样能够直接在异步事件后刷新界面。

    guava Event Bus 下载地址:https://code.google.com/p/guava-libraries/


    综合以上2个实例,这两种Event Bus的各自长处也非常明显,greenrobot Event Bus有四种模式抛出事件。guava Event Bus的异步实现比greenrobot来的方便,无需再抛MainThread事件了。源代码就不上了。大家动手写写能够加深印象。

  • 相关阅读:
    mem 预留内存
    关于内核反汇编,同时显示源文件
    读些笔记
    platform设备驱动
    glut 右键子菜单
    获取HINSTANCE
    window窗口样式style
    opengl 直线拾取
    glut弹出式菜单
    读取大恒采集卡c++代码
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6861304.html
Copyright © 2011-2022 走看看