RxAndroid 主/子线程切换配合的三种方式

2023-10-22 19:30

本文主要是介绍RxAndroid 主/子线程切换配合的三种方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我使用RxJava和RxAndroid的一个主要目的就是为了让逻辑复杂的业务需求在代码表现上不会特别混乱,以前在接手别人的项目的时候,经常碰到if else嵌套好几层的情况,还有当同一页面上出现好多异步任务的时候,会出现大量的回调的嵌套,程序员往往分了很多的函数东一笔西一笔的,读起来非常困难。

而RxJava解决这类问题就很得心应手,RxJava可以把复杂的业务逻辑用一条线串连起来,没有复杂的回调嵌套,也不会出现大型项目中常见的“谜之缩进”的代码,更可贵的是RxJava在处理异常上比传统try catch好的多,让代码更整洁和逻辑清晰。尤其在一项业务涉及到好多个网络接口,数据库查询,和一些耗时的计算操作,非常适合使用RxJava的方式将主线程和子线程执行的动作串联在一张页面上,通过自上而下的阅读代码就可以理清楚整个业务流程,对于大型项目来说非常实用。

这里写一个小demo来演示RxAndroid在碰到很多异步任务的情况下,在主线程和子线程之间灵活切换的案例。

比如现在有这样一个需求,给出一个url,如http://qduxsh.zz.vc/html/article.php?id=33,取出这个url中的协议名“http”,域名“qduxsh.zz.vc”,和api地址“/html/article.php”和全部的get请求参数“id=33”


方式一:异步任务式调用

现在我们假设从url中解析出这些信息是一个非常耗时的操作,需要放在子线程中执行,并在全部结果均获取完毕后显示在UI上,那么使用RxJava可以像下面一样,使用有点像AsynTask的写法实现不同线程的异步回调

/*** 一个简单的封装类*/public class UrlEntity{public String protocol;public String host;public String api;public String params;}

final String url = "http://qduxsh.zz.vc/html/article.php?id=33";Observable.create(new Observable.OnSubscribe<UrlEntity>() {@Overridepublic void call(Subscriber<? super UrlEntity> subscriber) {//子线程执行的方法Log.i("Alex", "call()执行线程是" + Thread.currentThread().getName() + "线程优先级=" + Thread.currentThread().getPriority() + "  线程id=" + Thread.currentThread().getId());//假设一下几行处理都是耗时操作Uri uri = Uri.parse(url);String protocol = uri.getScheme();String host = uri.getHost();String api = uri.getPath();String params = url.substring(url.lastIndexOf('?')+1,url.length());UrlEntity entity = new UrlEntity();entity.protocol = protocol;entity.host = host;entity.api = api;entity.params = params;//以上内容均在子线程执行//现在开始触发主线程的回调subscriber.onNext(entity);subscriber.onCompleted();}}).subscribeOn(Schedulers.computation()) // 指定 subscribe() 发生在 运算 线程.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程.subscribe(new Observer<UrlEntity>() {@Overridepublic void onNext(UrlEntity entity) {//主线程执行的方法Log.i("Alex", "onNext()执行线程是" + Thread.currentThread().getName() + "线程优先级=" + Thread.currentThread().getPriority() + "  线程id=" + Thread.currentThread().getId());TextView tv_protocol = (TextView) findViewById(R.id.tv_protocol);tv_protocol.setText(entity.protocol);TextView tv_host = (TextView) findViewById(R.id.tv_host);tv_host.setText(entity.host);TextView tv_api = (TextView) findViewById(R.id.tv_api);tv_api.setText(entity.api);TextView tv_param_list = (TextView) findViewById(R.id.tv_param_list);tv_param_list.setText(entity.params);}@Overridepublic void onCompleted() {Log.i("Alex", "onCompleted");}@Overridepublic void onError(Throwable e) {Log.i("ALex", "出现了异常", e);Toast.makeText(MainActivity.this, "Error!", Toast.LENGTH_SHORT).show();}});

那么现在肯定有人会说了,AsynTask也可以实现同样的效果,而且代码比这个更简洁易懂,那么我们还要RxJava干什么,但是假如我们现在修改一下需求,不要等协议,域名,api,参数都解析完毕才显示在UI上,而是这几个需求同时解析,谁先解析完谁就先显示,让用户尽快的看到页面的变化,那么用RxJava写应该如何呢?

方式二:子线程分步任务逐个回调

public enum Type {host,protocol,api,params}public static class KeyValue{public Type type;public String value;public KeyValue(Type type, String value) {this.type = type;

这篇关于RxAndroid 主/子线程切换配合的三种方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/263171

相关文章

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

用命令行的方式启动.netcore webapi

用命令行的方式启动.netcore web项目 进入指定的项目文件夹,比如我发布后的代码放在下面文件夹中 在此地址栏中输入“cmd”,打开命令提示符,进入到发布代码目录 命令行启动.netcore项目的命令为:  dotnet 项目启动文件.dll --urls="http://*:对外端口" --ip="本机ip" --port=项目内部端口 例: dotnet Imagine.M

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

【即时通讯】轮询方式实现

技术栈 LayUI、jQuery实现前端效果。django4.2、django-ninja实现后端接口。 代码仓 - 后端 代码仓 - 前端 实现功能 首次访问页面并发送消息时需要设置昵称发送内容为空时要提示用户不能发送空消息前端定时获取消息,然后展示在页面上。 效果展示 首次发送需要设置昵称 发送消息与消息展示 提示用户不能发送空消息 后端接口 发送消息 DB = []@ro

脏页的标记方式详解

脏页的标记方式 一、引言 在数据库系统中,脏页是指那些被修改过但还未写入磁盘的数据页。为了有效地管理这些脏页并确保数据的一致性,数据库需要对脏页进行标记。了解脏页的标记方式对于理解数据库的内部工作机制和优化性能至关重要。 二、脏页产生的过程 当数据库中的数据被修改时,这些修改首先会在内存中的缓冲池(Buffer Pool)中进行。例如,执行一条 UPDATE 语句修改了某一行数据,对应的缓

MyBatis 切换不同的类型数据库方案

下属案例例当前结合SpringBoot 配置进行讲解。 背景: 实现一个工程里面在部署阶段支持切换不同类型数据库支持。 方案一 数据源配置 关键代码(是什么数据库,该怎么配就怎么配) spring:datasource:name: test# 使用druid数据源type: com.alibaba.druid.pool.DruidDataSource# @需要修改 数据库连接及驱动u

线程的四种操作

所属专栏:Java学习        1. 线程的开启 start和run的区别: run:描述了线程要执行的任务,也可以称为线程的入口 start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api

Java 多线程的基本方式

Java 多线程的基本方式 基础实现两种方式: 通过实现Callable 接口方式(可得到返回值):

前端form表单+ifarme方式实现大文件下载

// main.jsimport Vue from 'vue';import App from './App.vue';import { downloadTokenFile } from '@/path/to/your/function'; // 替换为您的函数路径// 将 downloadTokenFile 添加到 Vue 原型上Vue.prototype.$downloadTokenF

SigLIP——采用sigmoid损失的图文预训练方式

SigLIP——采用sigmoid损失的图文预训练方式 FesianXu 20240825 at Wechat Search Team 前言 CLIP中的infoNCE损失是一种对比性损失,在SigLIP这个工作中,作者提出采用非对比性的sigmoid损失,能够更高效地进行图文预训练,本文进行介绍。如有谬误请见谅并联系指出,本文遵守CC 4.0 BY-SA版权协议,转载请联系作者并注