Android Studio:如何用一个store类管理事件、简化管理
一、完整代码
public abstract class Store<T extends Action> extends ICompositeSubscription {
private RxBus mRxBus;
public Store() {
mRxBus = new RxBus();
}
/**
* 发送事件
*
* @param object
*/
public void dispatcherStore(Object object) {
this.mRxBus.post(object);
}
public void onAction(T action) {
switch (action.getType()) {
case Action.STATE_ERROR_ACTION:
Object object = action.getData();
if (null != object) {
// 网络连接错误
if (action.getData() instanceof UnknownHostException) {
dispatcherStore(new AppErrorState(606));
return;
}
if (object instanceof DataContainer) {
DataContainer container = (DataContainer) action.getData();
// tokenId 不可用
if (container.Code == 300) {
dispatcherStore(new AppErrorState(300));
} else {
dispatcherStore(new ErrorState(container.ErrCode, container.Message));
}
return;
}
// 系统错误
dispatcherStore(new AppErrorState(500));
}
break;
default:
try {
doAction(action);
} catch (ClassCastException ex) {
return;
}
break;
}
}
/**
* 添加观察者
*
* @param type
* @param <T>
* @return
*/
public <T> Observable<T> toObservable(Class<T> type) {
return mRxBus.toObservable(type);
}
public <T> Subscription toSubscription(Class<T> type, Action1<T> action1, Scheduler scheduler) {
return mRxBus.toSubscription(type, action1, scheduler);
}
/**
* 在主线程里执行订阅者
*
* @param type
* @param action1
* @param <T>
* @return
*/
public <T> Subscription toMainSubscription(Class<T> type, Action1<T> action1) {
Subscription sub = mRxBus.toSubscription(type, action1);
return putSubscription(sub);
}
public abstract void doAction(T action);
public static class NetErrorEvent {
}
public static class ErrorState {
public int state;
public String msge;
public ErrorState(int state) {
this.state = state;
}
public ErrorState(int state, String msge) {
this.state = state;
this.msge = msge;
}
public ErrorState() {
}
}
public static class AppErrorState {
public int state;
public AppErrorState(int state) {
this.state = state;
}
}
}
二、代码解释
public abstract class Store<T extends Action> extends ICompositeSubscription {
Store<T extends Action>
这个语法是 Java 中的泛型声明,意味着 Store
类是一个泛型类,它的类型参数 T
必须是 Action
类或其子类。
ICompositeSubscription是一个订阅管理工具,把所有的订阅纳入管理,方便在活动销毁的时候对订阅进行统一的清理。
private RxBus mRxBus;
这个变量是用来发射和订阅事件流的变量。
public Store() {
mRxBus = new RxBus();
}
无参构造函数。
public void dispatcherStore(Object object) {
this.mRxBus.post(object);
}
dispatcherStore
方法用于 发布事件。它将事件对象通过 mRxBus.post(object)
发布出去,所有订阅该事件的观察者都会接收到这个事件。
onAction 方法:
onAction
方法是处理传入的Action
对象的核心方法。它根据Action
的类型,决定如何处理不同的事件。- 如果事件类型是
STATE_ERROR_ACTION
,它会处理错误相关的逻辑,并根据数据类型进行不同的处理:- 网络错误:如果
action.getData()
是UnknownHostException
,它会发布一个AppErrorState(606)
事件。 - 数据容器错误:如果
action.getData()
是DataContainer
,根据其Code
判断不同的错误类型(例如,Code == 300
表示 token 无效)。 - 系统错误:如果以上情况都不满足,默认发送
AppErrorState(500)
。
- 网络错误:如果
- 如果事件类型不是
STATE_ERROR_ACTION
,它将调用doAction
方法进行处理。
public <T> Observable<T> toObservable(Class<T> type) {
return mRxBus.toObservable(type);
}
toObservable
方法将事件类型T
转换为一个Observable
对象。这个Observable
可以被订阅,从而接收RxBus
发布的事件。type
是事件的类型(如NetErrorEvent
、ErrorState
等)。
public <T> Subscription toSubscription(Class<T> type, Action1<T> action1, Scheduler scheduler) {
return mRxBus.toSubscription(type, action1, scheduler);
}
toSubscription
方法用于订阅一个事件类型,并指定一个处理逻辑 action1
。该方法还允许指定一个 Scheduler
,用于决定在哪个线程上处理事件。
type
:要订阅的事件类型。action1
:事件处理逻辑,当事件发生时执行该处理逻辑。scheduler
:指定线程调度,决定在哪个线程上执行action1
。
public <T> Subscription toMainSubscription(Class<T> type, Action1<T> action1) {
Subscription sub = mRxBus.toSubscription(type, action1);
return putSubscription(sub);
}
toMainSubscription
方法是将事件的订阅放到主线程中执行(通常是 UI 线程)。它创建了一个Subscription
并调用putSubscription(sub)
将其保存或管理。putSubscription
很可能用于管理和取消订阅,防止内存泄漏。
三、使用store的实例
要使用 Store
类,我们需要做以下几件事情:
- 定义一个具体的
Store
子类:因为Store
是一个抽象类,我们需要继承它并实现doAction
方法,处理特定类型的事件。 - 创建和发布
Action
对象:在Store
中发布事件时,我们会创建一个Action
对象并通过dispatcherStore
方法发布。 - 订阅
Action
对象:在合适的地方,我们可以通过Store
类的订阅方法来订阅事件,并处理收到的事件。
步骤 1: 定义一个具体的 Store
子类
首先,我们需要定义一个 Store
子类,并实现 doAction
方法:
public class MyStore extends Store<MyAction> {
@Override
public void doAction(MyAction action) {
// 处理 MyAction 类型的事件
switch (action.getType()) {
case MyAction.ACTION_TYPE:
// 处理特定类型的 Action
MyData data = (MyData) action.getData();
// 处理数据...
System.out.println("Received data: " + data);
break;
default:
System.out.println("Unknown action type");
}
}
}
MyStore
继承自Store
并指定MyAction
为事件类型。可以根据业务需求来实现doAction
方法,处理特定类型的事件。MyAction
是自定义的Action
子类,包含事件类型和数据。
步骤 2: 定义一个具体的 Action
子类
public class MyAction extends Action<MyData> {
public static final String ACTION_TYPE = "my_action";
public MyAction(MyData data) {
super(ACTION_TYPE, data);
}
}
MyAction
是一个具体的事件类,继承自 Action
。它将 MyData
作为事件的数据类型,并指定事件类型为 ACTION_TYPE
。
步骤 3: 定义事件数据类
public class MyData {
private String message;
public MyData(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
MyData
是用来传递数据的实体类。在 MyAction
中,我们将 MyData
作为事件的数据。
步骤 4: 使用 Store
发布和订阅事件
创建 Store
实例并发布事件
在你的业务逻辑中,创建 MyStore
实例并使用它来发布事件:
public class MainActivity {
public static void main(String[] args) {
// 创建 Store 实例
MyStore myStore = new MyStore();
// 创建事件数据
MyData data = new MyData("Hello, World!");
// 创建并发布事件
MyAction action = new MyAction(data);
myStore.dispatcherStore(action);
}
}
在 MainActivity
中,我们创建了 MyStore
的实例,并创建了一个 MyAction
事件,随后通过 dispatcherStore
发布该事件。
订阅事件
为了响应 MyAction
事件,你需要订阅它并处理:
public class MainActivity {
public static void main(String[] args) {
// 创建 Store 实例
MyStore myStore = new MyStore();
// 订阅 MyAction 类型的事件
myStore.toMainSubscription(MyAction.class, new Action1<MyAction>() {
@Override
public void call(MyAction action) {
// 处理事件
MyData data = action.getData();
System.out.println("Received action: " + action.getType() + ", data: " + data.getMessage());
}
});
// 创建事件数据
MyData data = new MyData("Hello, World!");
// 创建并发布事件
MyAction action = new MyAction(data);
myStore.dispatcherStore(action);
}
}
toMainSubscription
方法将订阅MyAction
类型的事件,并在事件发布时执行指定的Action1
处理逻辑。- 在
call
方法中,我们提取了action
的数据并打印出来。
完整代码
// MyData.java
public class MyData {
private String message;
public MyData(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
// MyAction.java
public class MyAction extends Action<MyData> {
public static final String ACTION_TYPE = "my_action";
public MyAction(MyData data) {
super(ACTION_TYPE, data);
}
}
// MyStore.java
public class MyStore extends Store<MyAction> {
@Override
public void doAction(MyAction action) {
switch (action.getType()) {
case MyAction.ACTION_TYPE:
MyData data = (MyData) action.getData();
System.out.println("Received data: " + data.getMessage());
break;
default:
System.out.println("Unknown action type");
}
}
}
// MainActivity.java
public class MainActivity {
public static void main(String[] args) {
// 创建 Store 实例
MyStore myStore = new MyStore();
// 订阅 MyAction 类型的事件
myStore.toMainSubscription(MyAction.class, new Action1<MyAction>() {
@Override
public void call(MyAction action) {
// 处理事件
MyData data = action.getData();
System.out.println("Received action: " + action.getType() + ", data: " + data.getMessage());
}
});
// 创建事件数据
MyData data = new MyData("Hello, World!");
// 创建并发布事件
MyAction action = new MyAction(data);
myStore.dispatcherStore(action);
}
}
解释
MyData
:存储事件数据的类,包含消息字段。MyAction
:事件类,继承自Action<MyData>
,用于封装MyData
数据。MyStore
:继承自Store
,实现了doAction
方法,处理事件类型为MyAction
的事件。MainActivity
:- 创建
MyStore
实例并订阅MyAction
事件。 - 创建
MyAction
事件并通过dispatcherStore
发布。 - 订阅事件后,在
call
方法中处理并打印事件数据。
- 创建
输出
Received action: my_action, data: Hello, World!
Received data: Hello, World!