首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这是使用事件总线的正确方式吗?

这是使用事件总线的正确方式吗?
EN

Stack Overflow用户
提问于 2016-02-24 14:19:15
回答 1查看 1.6K关注 0票数 1

我计划添加Otto事件总线,以使我的通信解耦。我希望使用事件总线的一件事是在按钮单击处理程序和活动之间进行通信。

这个想法是,按钮单击(从我的自定义视图)将生成一个文本提交事件,它将通知活动。然后,活动将决定如何处理它。如果活动认为是正确的,它会将文本发送到一个服务上传或其他。

这是使用事件总线的正确方式吗?

另外,在使用事件总线时,有哪些好的做法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-24 22:58:39

我仍然认为这个问题对于StackOverflow模型来说是不合适的。

但是对于任何关注的人来说,如何在总线上组织用户活动,这就是我们在我工作的地方所做的事情。

记住,这种类型的结构只有在您创建一个大项目时才有意义,在这个项目中,实现高度的分离会使开发人员的生活更加轻松。对于小型的、快速的项目或测试应用程序来说,这太费劲了。

PS.:下面的所有代码都是100%的输入,没有检查任何真正的代码,所以会有排字和小错误,但应该足够了解这种方法。我也没有写任何像@override这样的注释,对它来说太懒了。

First:活动覆盖getSystemService,通过上下文提供总线,并根据需要注册/注销事件处理程序。

代码语言:javascript
复制
public MyActivity extends AppCompatActivity {
    private static final String BUS_SERVICE = "bus_service";

    private List<EventHandler> eventHandlers = new ArrayList();
    private Bus bus = new Bus();

    public void onCreate(Bundle savedState){
        super.onCreate(savedState);
            .... layout creation, etc, etc, etc

            if(isLoggedIn()) {
                eventHandlers.add(new LoggedUserNavigationHandler());
                eventHandlers.add(new RestPostRequestHandler());
            } else{
                eventHandlers.add(new GuestUserNavigation());
            }
            eventHandlers.add(new AnalyticsTrackingHandler());

            if(DEBUG) {
                // log all events in debug mode
                eventHandlers.add(new EventHandler(){
                             @Subscribe
                             public void onEvent(Object o){
                                 Log.d(TAG, "Event: " + o.toString);
                             }
                        });
            }

        }   
    }

    public Object getSystemService(String name){
        if(BUS_SERVICE.equals(name)) return bus;
        else return super.getSystemService(name);
    }

    public void onStart(){
        super.onStart();
        for(int i=0, size=eventHandlers.size(); i<size; i++) {
             eventHandlers.get(i).activity = this; // pass reference, might be usefull
             bus.register(eventHandlers.get(i));
        }
    }
    public void onStop(){
        for(int i=0, size=eventHandlers.size(); i<size; i++) {
             bus.unregister(eventHandlers.get(i));
             eventHandlers.get(i).activity = null;
        }
        super.onStop();
    }
}

然后是:您有所有的RecyclerView.ViewHolder (或自定义小部件)作为单击监听器并分派适当的事件。例如,在照片项目的ViewHolder中。

代码语言:javascript
复制
public class PhotoHolder extends ViewHolder implements OnClickListener {

     TextView user;
     ImageButton like;
     ImageView photo;

     Photo data; // assume this was set during `bindViewHolder`

     public PhotoHolder(View itemView) {
          super(itemView);
          user = (TextView) itemView.findViewById(...
          like = (ImageButton) itemView.findViewById(...
          photo = (ImageView) itemView.findViewById(...

          user.setOnClickListener(this);
          like.setOnClickListener(this);
          photo.setOnClickListener(this);
     }

     public void onClick(View view){
          switch(view.getId()){
              case R.id.user:
                   ((Bus)view.getSystemService(BUS_SERVICE))
                              .post(new Event.PhotoEvent.UserTap(data);
                 break;
              case R.id.like:
                   ((Bus)view.getSystemService(BUS_SERVICE))
                              .post(new Event.PhotoEvent.LikeUnlike(data);
                 break;
              case R.id.photo:
                   ((Bus)view.getSystemService(BUS_SERVICE))
                              .post(new Event.PhotoEvent.PhotoTap(data);
                 break;
          }
     }
}

和最后一个当然是:是创建那些事件对象,并将所有事件添加到适当的处理程序中。

代码语言:javascript
复制
// add all the app events under this class, or maybe create a `Event` package and then all the events in that package
public final class Event {

    public static class PhotoEvent {
          public final Photo data;
          public Photo(Photo data){
              this.data=data;
          }

          public static class UserTap extends PhotoEvent{
                // copy matching constructor
          }

          public static class LikeUnlike extends PhotoEvent{
                // copy matching constructor
          }

          public static class PhotoTap extends PhotoEvent{
                // copy matching constructor
          }

    }
}

最后,处理事件

代码语言:javascript
复制
public class RestPostRequestHandler {

     @Subscribe
     public void onPhotoLikeUnlike(Event.Photo.LikeUnlike event){
         // make your POST request here
     }
}

用于导航的处理程序:

代码语言:javascript
复制
public class LoggedUserNavigationHandler extends EventHandler{

     @Subscribe
     public void on(Event.Photo.UserTap event){
          Intent i = new Intent( ... create here intent for the "user profile"
          // activity reference was passed during onStart
          activity.startActivity(i);
     }
}

迷幻剂的处理者:

代码语言:javascript
复制
 public class AnalyticsTrack {
     @Subscribe
     public void on(Event.Photo.UserTap event){
          // send event "user tap" ?
     }
 }

我同意一些评论,即当“点击”公共汽车上的事件时,可以创建一个巨大的、奇怪的意大利面代码。但是,如果从一开始就定义了一种良好的结构化方法,并且所有的开发人员都遵循它,那么您就可以实现一个易于跟踪的项目,并且可以非常明确地分离职责。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35604641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档