我之前写过一篇文章“Android开发之局部广播的使用”,地址:http://blog.csdn.net/jarchie520/article/details/71434833,在这篇文章里面使用的方法也能够实现今天所要讲的这个功能,组件间通信。但是那种实现方式相对来说比较麻烦,今天我们来使用一种比较流行的方式——EventBus,话说这个库现在已经更新到3.0的版本了,才想起来去说说它的用法,很是惭愧啊。下面不如正题,一起来看具体用法。
一、先来看看它的基本介绍
这里我截取了它的官网上的一段说明,上面一段是它的简单介绍:EventBus是Android和Java平台的一款基于发布/订阅模式的开源库,它支持已简单的几行代码来解耦类,简化代码,消除依赖关系,加快开发速度等。下面则是它的一些优点的介绍,我们可以看到第一点就是简化组件间的通信,可见这也是它的主要功能点,因此我们很有必要来认真学习并使用一下它。官网地址:http://greenrobot.org/eventbus/,需要的朋友可以进去看一下。
二、项目地址(GitHub地址):https://github.com/greenrobot/EventBus
依赖方式:我们在build.gradle文件的dependencies闭包中添加如下依赖:compile 'org.greenrobot:eventbus:3.1.1'
三、具体使用
这里我是直接拿我之前写的一个小项目里面的登录模块来加以说明,这里采用的是MVP的架构模式,有些代码可能看不到,文末我会给出项目地址,需要的可以去查看完整代码。
1、首先来看布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gray_bg"
android:gravity="center_horizontal"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/AppTheme.Toolbar"
app:navigationIcon="?attr/homeAsUpIndicator"
app:title="@string/title_login" />
<android.support.design.widget.TextInputLayout
android:id="@+id/layout_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:gravity="center_horizontal"
app:hintTextAppearance="@style/FloatingStyle">
<EditText
android:id="@+id/edit_username"
android:layout_width="260dp"
android:layout_height="wrap_content"
android:inputType="text"
android:maxLines="1"
android:padding="5dp"
android:textColor="@color/black"
android:textColorHint="@color/colorAccent" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/layout_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
app:hintTextAppearance="@style/FloatingStyle">
<EditText
android:id="@+id/edit_password"
android:layout_width="260dp"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:maxLines="1"
android:padding="5dp"
android:textColor="@color/black"
android:textColorHint="@color/colorAccent" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/btn_login"
android:layout_width="240dp"
android:layout_height="35dp"
android:layout_marginTop="20dp"
android:background="@drawable/button_bg"
android:text="@string/login"
android:textColor="@color/white" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/tv_go_register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:layout_marginTop="8dp"
android:text="@string/go_register"
android:textColor="@color/colorPrimary"
android:textSize="14sp" />
<CheckBox
android:id="@+id/save_pwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:text="@string/sava_pwd"
android:textColor="@color/colorPrimary" />
</RelativeLayout>
</LinearLayout>
这里要处理的业务是当我们点击登录按钮时,从登录页跳转到我的页面,更新用户信息。
2、创建消息实体类,这里创建的是:RegisterEvent.java
package com.jarchie.seemovies.bean;
/**
* Created by Jarchie on 2017\11\16.
* 描述:创建事件实体类
*/
public class RegisterEvent {
private String message;
private String imgUrl;
public RegisterEvent() {}
public RegisterEvent(String message) {
this.message = message;
}
public RegisterEvent(String message, String imgUrl) {
this.message = message;
this.imgUrl = imgUrl;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
3、完成订阅,在我的页面中注册、声明订阅方法以及解绑注册
首先我们在onCreate()方法中完成注册:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this); //注册成为订阅者
}
接着,我们需要在这个页面中声明一个订阅方法,用于接收事件,在EventBus3.0中声明订阅方法需要用到@Subscribe注解,方法名称你开心就好任意指定,权限必须是public的,方法参数有且只能有一个,参数类型就是上面定义好的事件实体类型(这里是RegisterEvent类型),具体代码如下所示:
//订阅方法,当接收到事件时会调用这个方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void onRegisterEvent(RegisterEvent event) {
tvLogin.setText(event.getMessage());
loginState = SharePreUtils.getBoolean(getContext(), Constant.LOGINED, false);
presenter.refreshLoginState(loginState, getContext(), tvLogin, loginOutBtn);
}
最后,当订阅者不再需要接收事件时,我们需要解除注册,释放内存,防止内存泄漏:
@Override
public void onDestroy() { //取消注册
super.onDestroy();
ImageUtils.putImageToShareUtil(getContext(),mImageView);
EventBus.getDefault().unregister(this);
}
4、发布事件,在登录页中点击按钮的时候发送事件
EventBus底层对观察者模式做了封装,这里当有事件发送时,被观察者会通知所有注册了该事件的观察者对被观察者的这一事件做出及时的响应,代码如下:
//利用EventBus发送事件
EventBus.getDefault().post(new RegisterEvent(editUserName.getText().toString()));
通过这样简单的几步操作,我们就可以很方便的完成组件间的通信了,可以看到代码还是很少的,使用起来也是挺方便的。
因为这是从一个小项目里面摘出来的代码,所以只截取了功能代码,完整代码请移步至:https://gitee.com/jarchie/SeeMovies
今天就写到这里了,希望共同进步!