当前位置: 首页 > news >正文

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 是事件的类型(如 NetErrorEventErrorState 等)。

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 类,我们需要做以下几件事情:

  1. 定义一个具体的 Store 子类:因为 Store 是一个抽象类,我们需要继承它并实现 doAction 方法,处理特定类型的事件。
  2. 创建和发布 Action 对象:在 Store 中发布事件时,我们会创建一个 Action 对象并通过 dispatcherStore 方法发布。
  3. 订阅 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);
    }
}

解释

  1. MyData:存储事件数据的类,包含消息字段。
  2. MyAction:事件类,继承自 Action<MyData>,用于封装 MyData 数据。
  3. MyStore:继承自 Store,实现了 doAction 方法,处理事件类型为 MyAction 的事件。
  4. MainActivity
    • 创建 MyStore 实例并订阅 MyAction 事件。
    • 创建 MyAction 事件并通过 dispatcherStore 发布。
    • 订阅事件后,在 call 方法中处理并打印事件数据。

输出

 

Received action: my_action, data: Hello, World!
Received data: Hello, World!

相关文章:

  • 详解AbstractQueuedSynchronizer(AQS)源码
  • 考场考试监考系统
  • QT自定义扫描控件,支持任意方位拖动和拖动扫描范围。
  • 数据结构(查找)
  • Python高级语法之urllib
  • Android Studio打包APK
  • 数字化赋能,3D数字博物馆开启沉浸式体验
  • 机器学习(李宏毅)——RNN
  • 第一章 初识LLMs
  • 基于python深度学习遥感影像地物分类与目标识别、分割实践技术应用
  • 从零搭建SpringBoot3+Vue3前后端分离项目基座,中小项目可用
  • Navicat Premium17 连接Oracle出现 “未加载 Oracle库
  • IDEA集成DeepSeek AI助手完整指南
  • 打开多个chrome历史记录
  • JAVA监听器(学习自用)
  • BEV:车轮接地点车辆修正3D框位置精度
  • 【数据结构】(10) 排序算法
  • 设计模式之适配模式是什么?以及在Spring AOP中的拦截器链的使用源码解析。
  • FreeSwitch的应用类模块
  • Python跨年烟花
  • 范志毅跨界归来做青训,探索中国足球人才培养新模式
  • 绿城约13.93亿元竞得西安浐灞国际港港务片区地块,区内土地楼面单价首次冲破万元
  • 牛市早报|央行宣布降准降息,公募基金改革最新方案落地
  • 湖南张家界警方公告宣布一名外国人居留许可作废
  • 印官员称巴基斯坦在克什米尔实控线附近开火已致7死38伤
  • 大规模空袭也门一日后,以军又对也门萨那机场发出撤离警告