文章目录
前言
一、根据不同的线程模式进行不同的线程切换操作
二、完整代码示例
前言
发布线程发布事件之后 , 消息中心需要转发这些事件 , 并执行相应的订阅方法 ;
在转发的过程中 , 需要针对订阅方法的 @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; } }