【EventBus】事件通信框架 ( 发送事件 | 判断发布线程是否是主线程 | 子线程切换主线程 | 主线程切换子线程 )(一)

简介: 【EventBus】事件通信框架 ( 发送事件 | 判断发布线程是否是主线程 | 子线程切换主线程 | 主线程切换子线程 )(一)

文章目录

前言

一、根据不同的线程模式进行不同的线程切换操作

二、完整代码示例

前言

发布线程发布事件之后 , 消息中心需要转发这些事件 , 并执行相应的订阅方法 ;


在转发的过程中 , 需要针对订阅方法的 @Subscribe 注解的不同 threadMode 属性进行不同的线程模式处理 ;


假如订阅方法的线程模式属性属性是 POSTING , 直接在发布线程中调用订阅方法 ;


假如订阅方法的线程模式属性属性是 MAIN , 则需要判定发布线程是否是主线程 ;


如果发布线程是主线程 , 则直接执行订阅方法 ;

如果发布线程不是主线程 , 则需要在主线程中执行订阅方法 ;

假如订阅方法的线程模式属性是 BACKGROUND , 则需要判定发布线程是否是主线程 ;


如果发布线程是主线程 , 则切换到子线程执行订阅方法 ;

如果发布线程不是主线程 , 则直接执行订阅方法 ;


可参考 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 ) 博客的部分操作 ;






一、根据不同的线程模式进行不同的线程切换操作


首先 , 获取当前线程是否是主线程 : 参考 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 ) 一、判定当前线程是否是主线程 博客章节 ;


     

// 判断当前线程是否是主线程
        //      获取 mainLooper 与 myLooper 进行比较 , 如果一致 , 说明该线程是主线程
        boolean isMainThread = false;
        // 下面的情况下 , 线程是主线程
        if (Looper.getMainLooper() == Looper.myLooper()) {
            isMainThread = true;
        }


然后 , 获取订阅方法的线程模式 , 不同的线程模式进行不同的处理 ;


 

// 判断订阅方法的线程模式
        MyThreadMode threadMode = subscription.getSubscriberMethod().getThreadMode();
        switch (threadMode) {
            case POSTING:
                break;
            case MAIN:
                break;
            case MAIN_ORDERED:
                break;
            case BACKGROUND:
                break;
            case ASYNC:
                break;
        }


POSTING 线程模式下 , 不进行线程切换 , 直接调用反射方法执行订阅方法即可 ;


       

case POSTING:
                // 直接在发布线程调用订阅方法
                invokeMethod(subscription, event);
                break;


MAIN 线程模式下 , 需要判定发布线程是否是主线程 ;


如果发布线程是主线程 , 则直接执行订阅方法 ;

如果发布线程不是主线程 , 则需要在主线程中执行订阅方法 ;

为了方便 , 这里将 MAIN_ORDERED 与 MAIN 分支进行合并处理 ;


参考 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 ) 二、子线程中执行主线程方法 博客章节 ;


     

case MAIN:
            case MAIN_ORDERED:
                // 如果发布线程是主线程, 直接调用
                if (isMainThread) {
                    invokeMethod(subscription, event);
                } else {
                    // 将订阅方法放到主线程执行
                    // 获取主线程 Looper , 并通过 Looper 创建 Handler
                    Handler handler = new Handler(Looper.getMainLooper());
                    // 在主线程中执行订阅方法
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            invokeMethod(subscription, event);
                        }
                    });
                }
                break;


BACKGROUND 线程模式下 , 判定发布线程是否是主线程 ;


如果发布线程是主线程 , 则切换到子线程执行订阅方法 ;

如果发布线程不是主线程 , 则直接执行订阅方法 ;

为了方便 , 这里将 ASYNC 与 BACKGROUND 分支进行合并处理 ;


参考 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 ) 三、主线程中执行子线程方法 博客章节 ;


     

case BACKGROUND:
            case ASYNC:
                // 如果是主线程 , 切换到子线程执行
                if (isMainThread) {
                    // 在线程池中执行方法
                    executorService.execute(new Runnable() {
                        @Override
                        public void run() {
                            invokeMethod(subscription, event);
                        }
                    });
                } else {
                    // 如果是子线程直接执行
                    invokeMethod(subscription, event);
                }
                break;


部分代码示例 :


 

/**
     * 调用订阅方法
     * @param subscription
     * @param event
     */
    private void postSingleSubscription(MySubscription subscription, Object event) {
        // 判断当前线程是否是主线程
        //      获取 mainLooper 与 myLooper 进行比较 , 如果一致 , 说明该线程是主线程
        boolean isMainThread = false;
        // 下面的情况下 , 线程是主线程
        if (Looper.getMainLooper() == Looper.myLooper()) {
            isMainThread = true;
        }
        // 判断订阅方法的线程模式
        MyThreadMode threadMode = subscription.getSubscriberMethod().getThreadMode();
        switch (threadMode) {
            case POSTING:
                // 直接在发布线程调用订阅方法
                invokeMethod(subscription, event);
                break;
            case MAIN:
            case MAIN_ORDERED:
                // 如果发布线程是主线程, 直接调用
                if (isMainThread) {
                    invokeMethod(subscription, event);
                } else {
                    // 将订阅方法放到主线程执行
                    // 获取主线程 Looper , 并通过 Looper 创建 Handler
                    Handler handler = new Handler(Looper.getMainLooper());
                    // 在主线程中执行订阅方法
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            invokeMethod(subscription, event);
                        }
                    });
                }
                break;
            case BACKGROUND:
            case ASYNC:
                // 如果是主线程 , 切换到子线程执行
                if (isMainThread) {
                    // 在线程池中执行方法
                    executorService.execute(new Runnable() {
                        @Override
                        public void run() {
                            invokeMethod(subscription, event);
                        }
                    });
                } else {
                    // 如果是子线程直接执行
                    invokeMethod(subscription, event);
                }
                break;
        }
    }





目录
相关文章
|
1月前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
2月前
|
Python
如何在Python中实现线程之间的同步和通信?
【2月更文挑战第17天】【2月更文挑战第51篇】如何在Python中实现线程之间的同步和通信?
|
2月前
|
人工智能 JSON 前端开发
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
|
2天前
|
存储 NoSQL Redis
深入浅出Redis(二):Redis单线程模型与通信流程
深入浅出Redis(二):Redis单线程模型与通信流程
|
12天前
|
Java
主线程等待子线程执行完毕再执行的几种方式
主线程等待子线程执行完毕再执行的几种方式
|
16天前
线程间的通信
线程间的通信
14 0
|
23天前
|
安全 Java 编译器
【JavaEE多线程】线程安全、锁机制及线程间通信
【JavaEE多线程】线程安全、锁机制及线程间通信
33 1
|
29天前
|
Java
Java线程通信的精髓:解析通知等待机制的工作原理
Java线程通信的精髓:解析通知等待机制的工作原理
27 3
Java线程通信的精髓:解析通知等待机制的工作原理
|
1月前
|
存储 缓存 Java
java多线程之线程通信工具类
java多线程之线程通信工具类
|
安全 Java 容器
高并发编程之线程间通信和集合的线程安全
高并发编程之线程间通信和集合的线程安全
24 1