Android RxJava2 整合Retrofit2 与Hilt注入网络模块

1.导入依赖

 //Retrofit 整合 RXjavaimplementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'implementation 'io.reactivex.rxjava2:rxjava:2.2.4'implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'//Retrofit//Retrofit 核心库implementation("com.squareup.retrofit2:retrofit:2.9.0")//响应数据自动序列化//JSONimplementation("com.squareup.retrofit2:converter-gson:2.9.0")//String类型implementation("com.squareup.retrofit2:converter-scalars:2.9.0")//拦截器 loggingimplementation("com.squareup.okhttp3:logging-interceptor:3.14.+")implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))//Hiltimplementation("com.google.dagger:hilt-android:2.44")annotationProcessor("com.google.dagger:hilt-android-compiler:2.44")compileOnly 'org.projectlombok:lombok:1.18.32'annotationProcessor 'org.projectlombok:lombok:1.18.32'testCompileOnly 'org.projectlombok:lombok:1.18.32'testAnnotationProcessor 'org.projectlombok:lombok:1.18.32'

在模块下build.gradle

加入插件

plugins {id 'com.android.application'id 'dagger.hilt.android.plugin'
}

项目工程build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {ext {agp_version = '7.4.2'}repositories {
//        maven {url = "https://maven.aliyun.com/nexus/content/groups/public/"}maven {url = "https://maven.aliyun.com/repository/public"}maven { url ="https://maven.aliyun.com/repository/google/"}maven { url= "https://maven.aliyun.com/repository/jcenter/"}google()jcenter()mavenCentral()gradlePluginPortal()maven { url 'https://jitpack.io' }}dependencies {classpath "com.android.tools.build:gradle:$agp_version"classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.15'classpath 'com.google.dagger:hilt-android-gradle-plugin:2.44'// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle files}
}allprojects {repositories {
//        maven {url = "https://mirrors.tencent.com/nexus/repository/maven-public/"}maven {url = "https://maven.aliyun.com/repository/public"}maven { url ="https://maven.aliyun.com/repository/google/"}maven { url= "https://maven.aliyun.com/repository/jcenter/"}google()jcenter()mavenCentral()maven { url 'https://jitpack.io' }}
}task clean(type: Delete) {delete rootProject.buildDir
}

2.Application注入Hilt注解

@HiltAndroidApp
public class APP_CONTEXT extends Application

3.网络模块的注入

import android.util.Log;import com.tiger.nfc_project.activities.APP_CONTEXT;import net.retrofit.service.ApiService;
import net.retrofit.service.StudyService;import java.util.concurrent.TimeUnit;import javax.inject.Singleton;import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.components.SingletonComponent;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;@InstallIn(SingletonComponent.class)
@Module
public class NetWorkModule {private static final String Tag = "Retrofit";@Singleton@ProvidesOkHttpClient provideOkHttpClient() {HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {@Overridepublic void log(String message) {Log.i(Tag, message);}}).setLevel(HttpLoggingInterceptor.Level.BODY);return new OkHttpClient.Builder()//连接超时.connectTimeout(1, TimeUnit.SECONDS)//读取超时.readTimeout(3,TimeUnit.SECONDS).addInterceptor(interceptor).build();}@Singleton@ProvidesRetrofit provideRetrofit(OkHttpClient client) {return new Retrofit.Builder().baseUrl(APP_CONTEXT.CRACK_URL + "/").client(client)
//                .addConverterFactory(ScalarsConverterFactory.create()).addConverterFactory(GsonConverterFactory.create())//添加Rxjava适配.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();}@Singleton@ProvidesApiService provideApiService(Retrofit retrofit) {return retrofit.create(ApiService.class);}@Singleton@ProvidesStudyService provideStudyService(Retrofit retrofit) {return retrofit.create(StudyService.class);}}

4.三个统一异常处理器

import android.util.Log;import com.google.gson.JsonParseException;import org.json.JSONException;import java.net.ConnectException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.ParseException;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;/*** 统一异常处理*/
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class ApiException extends Exception {private static final String Tag = "ApiException";public static final int UNKNOWN_ERROR = 1000;public static final int PARSE_ERROR = 1001;public static final int NETWORK_ERROR = 1002;public static final int INNER_ERROR = 500;private Integer code;private String errorMsg;private Throwable e;public ApiException(String errorMsg) {this.code = INNER_ERROR;this.errorMsg = errorMsg;}public ApiException(Integer code, String message) {super(message);this.code = code;this.errorMsg = message;}public ApiException(Integer code, String errorMsg, Throwable cause) {super(errorMsg, cause);this.code = code;this.errorMsg = errorMsg;this.e = cause;}public static ApiException handleException(Throwable e) {ApiException ex;if (e instanceof ApiException) {ex = (ApiException) e;} else if (e instanceof JsonParseException|| e instanceof JSONException|| e instanceof ParseException) {ex = new ApiException(PARSE_ERROR, "数据解析异常", e);} else if (e instanceof ConnectException|| e instanceof UnknownHostException|| e instanceof SocketException) {ex = new ApiException(NETWORK_ERROR, "网络异常", e);} else {ex = new ApiException(UNKNOWN_ERROR, "未知异常", e);}return ex;}public void printException() {try {int i = code;if (i >= 1000) {//真正错误Log.e(Tag, errorMsg, e);} else {Log.e(Tag, "code:" + code + ";msg:" + errorMsg);}} catch (Throwable e) {e.printStackTrace();}}}
import io.reactivex.functions.Consumer;/*** 通用处理异常回调的Consumer*/
public abstract class ErrorConsumer implements Consumer<Throwable> {@Overridepublic void accept(Throwable throwable) {ApiException ex;if (throwable instanceof  ApiException){ex =(ApiException) throwable;}else {ex = ApiException.handleException(throwable);}error(ex);}protected abstract void error(ApiException e);
}
import android.util.Log;import com.jsonutil.GsonUtils;import net.vo.ErrorResultVo;import io.reactivex.functions.Consumer;
import retrofit2.HttpException;/*** 异常处理的标准写法*/
public abstract class ExceptionConsumer implements Consumer<Throwable> {private static final String tag = "HttpException";private static final String tag1 = "Exception";@Overridepublic void accept(Throwable throwable) throws Exception {try {if (throwable instanceof HttpException){HttpException throwable2 = (HttpException) throwable;String errorJson = throwable2.response().errorBody().string();ErrorResultVo obj = GsonUtils.toObj(errorJson, ErrorResultVo.class);String message = obj.getMessage();Log.e(tag,message);callback(message);}else {Log.e(tag1,"内部错误",throwable);}} catch (Exception e) {Log.e(tag1,"异常处理失败错误",e);}}public abstract void callback(String errorMsg);}

5.响应

public interface IResponse<T> {boolean isSuccess();T getData();Integer getCode();String getMsg();}
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.disposables.CompositeDisposable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/***  响应的标准写法 以后 RESTFUL风格* @param <T>*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseStandard<T> implements ObservableTransformer<T, T> {private CompositeDisposable compositeDisposable;@Overridepublic ObservableSource<T> apply(Observable<T> upstream) {return upstream.doOnSubscribe(disposable -> {if (compositeDisposable != null) {//disposable主要是用来取消订阅的compositeDisposable.add(disposable);}}).flatMap(response -> {try {return Observable.just(response);} catch (Exception e) {e.printStackTrace();}return Observable.error(new Exception("响应数据格式有误"));});}/*** 获取ResponseTransformer** @param compositeDisposable* @param <U>* @return*/public static <U> ResponseStandard<U> obtain(CompositeDisposable compositeDisposable) {return new ResponseStandard<>(compositeDisposable);}public static <U> ResponseStandard<U> obtain() {return new ResponseStandard<>();}}
import net.retrofit.exeption.ApiException;import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 获取IResponse后判断请求结果,并获取data返回* Observable<IResponse<T>>  --> Observable<T>* 可以自己实现,这里只是一种思路* 这是有JSONObject 的写法* @param <T>*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseTransformer<T> implements ObservableTransformer<IResponse<T>, T> {private CompositeDisposable compositeDisposable;@Overridepublic ObservableSource<T> apply(Observable<IResponse<T>> upstream) {return upstream.doOnSubscribe(new Consumer<Disposable>() {@Overridepublic void accept(Disposable disposable) throws Exception {if (compositeDisposable != null) {//disposable主要是用来取消订阅的compositeDisposable.add(disposable);}}}).onErrorResumeNext(new Function<Throwable, ObservableSource<? extends IResponse<T>>>() {@Overridepublic ObservableSource<? extends IResponse<T>> apply(Throwable throwable) throws Exception {//出现异常后统一处理return Observable.error(ApiException.handleException(throwable));}}).flatMap(new Function<IResponse<T>, ObservableSource<? extends T>>() {@Overridepublic ObservableSource<? extends T> apply(IResponse<T> response) throws Exception {//这段逻辑是业务请求成功后,根据接口返回的数据做一些成功失败后的规范处理//这里已经高度封装,弊端就算没那么灵活//可以自己去实现BaseResponse,不一定要使用IResponse这种写法if (response.isSuccess()) {//若响应成功if (response.getData() != null) {return Observable.just(response.getData());} else {try {//规定好,如果没有返回,那么默认泛型为字符串;String s = "成功";T t = (T) s;return Observable.just(t);} catch (Exception e) {e.printStackTrace();}}}return Observable.error(new ApiException(response.getCode(), response.getMsg(), new Exception("出现正常请求的错误")));}});}/*** 获取ResponseTransformer** @param compositeDisposable* @param <U>* @return*/public static <U> ResponseTransformer<U> obtain(CompositeDisposable compositeDisposable) {return new ResponseTransformer<>(compositeDisposable);}public static <U> ResponseTransformer<U> obtain() {return new ResponseTransformer<>();}}

6.ApiService

import net.vo.JSONResult;import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Path;public interface ApiService {/*** ** @param * @param * @return*/@GET(PREFIX + "/authorize/user/{bb}/dev/{aa}")Observable<JSONResult<Boolean>>  cc(@Path("bb") String bb, @Path("aa") String aa);}

7.结果返回

/*** @ClassName JSONResult* @Description 自定义响应数据格(接口)*              200:表示成功*              500:表示错误*              501:bean验证错误*              502:拦截器拦截用户taken出错*              503:不具备角色功能*              505:异常抛出信息* @Author liuhongjian* @Date 2020/3/11 16:03* @Version 1.0**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JSONResult<T> implements IResponse<T> {public static final Integer SUCCESS =200;/*** 响应码*/private Integer status;/*** 响应信息*/private String msg;/*** 响应的数据*/private T data;/****/private String ok;@Overridepublic boolean isSuccess() {return SUCCESS.equals(status);}@Overridepublic Integer getCode() {return status;}
}
import java.io.Serializable;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class ErrorResultVo implements Serializable {private static final long serialVersionUID = -7634852916785258705L;private String code;private String message;
}

8. RxJAVA 执行异步

 Observable<String[]> firstOperation = Observable.fromCallable(() -> {return infos;});Observable<Boolean> secondOperation = firstOperation.flatMap(infos ->{return true;});Observable<Boolean> thirdOperation = secondOperation.flatMap(isAllowWrite ->{return    Observable.fromCallable(() -> {return true;});});Disposable disposable =  thirdOperation.subscribeOn(Schedulers.io()).subscribe(result -> {}, new ErrorConsumer() {@Overrideprotected void error(ApiException e) {//异常统一处理 子线程e.printException();//异常handler.sendEmptyMessage(NOT_SUPPORT_TAG);}});/*** 对资源对象统一管理*/compositeDisposable.add(disposable);}catch (Exception e){Log.e(Tag,"代理授权出现异常",e);}

9.rxjava基本操作

Observable.just("Hello").observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {@Overridepublic void accept(String s) throws Exception {// 在主线程中操作,例如更新 UItextView.setText(s);}});

10.GSON使用

public class GsonUtils {public static final Gson gson = new GsonBuilder().serializeNulls().setDateFormat("yyyy-MM-dd hh:mm:ss").create();public static String getJson(Object o){return gson.toJson(o);}public static <T> T toObj(String o,Class<T> tClass){return gson.fromJson(o,tClass);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/28979.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python工具箱系列(五十三)

​​水印 水印是一种常见的图片处理需求。当既需要展示&#xff0c;又需要保护知识产权时&#xff0c;就需要使用文字或者图片来打水印。下面的代码展示了文字水印与图片水印的过程。 ​--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown from pat…

游戏找不到steam_api64.dll无法继续执行代码的解决方法

在电脑使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“steam_api64.dll丢失”。那么&#xff0c;steam_api64.dll到底是干嘛的&#xff1f;为什么会丢失&#xff1f;对电脑有什么具体影响&#xff1f;如何解决这个问题&#xff1f;本文将为您详细…

Python基础教程(九):Lambda 函数

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

golang:对struct排序的方法

golang对struct排序的方法 以下代码示例&#xff0c;通过对Student 结构体的age字段进行从小到大和从大到小排序 方法一 使用 sort.Slice() 进行排序 package mainimport ("fmt""sort" )type Student struct {name stringage int }func main() {stude…

vivado NODE、PACKAGE_PIN

节点是Xilinx部件上用于路由连接或网络的设备对象。它是一个 WIRE集合&#xff0c;跨越多个瓦片&#xff0c;物理和电气 连接在一起。节点可以连接到单个SITE_&#xff0c; 而是简单地将NETs携带进、携带出或携带穿过站点。节点可以连接到 任何数量的PIP&#xff0c;并且也可以…

基于QT5.12.7的VTK8.2下的VS2015 X64源码编译以及测试

有一段时间没更新博客了&#xff0c;最近在考虑使用VTK作为软件的后处理显示&#xff0c;相比于OSG&#xff0c;VTK在后处理上集成了很多优秀的算法&#xff0c;使用起来比较方便&#xff0c;而且后处理一般不需要太多的交互&#xff0c;所以VTK是一个不错的选择。 之前对VTK了…

【多视图感知】BEVFormer: Learning Bird’s-Eye-View Representation

BEVFormer: Learning Bird’s-Eye-View Representation from Multi-Camera Images via Spatiotemporal Transformers 论文链接:http://arxiv.org/abs/2203.17270 代码链接:https://github.com/fundamentalvision/BEVFormer 一、摘要 本文提出了一种名为BEVFormer的新框架&am…

Android基础-如何获取通话状态

在Android系统中&#xff0c;获取通话状态是开发通信类应用时常见的需求之一。通话状态的获取有助于应用程序在特定情况下执行相应的操作&#xff0c;如调整音量、显示特定界面或执行其他与通话相关的任务。下面将详细阐述在Android中如何获取通话状态&#xff0c;内容将包括所…

数据库-数据定义和操纵-DDL语言的使用

创建一个数据库&#xff1a; create database 数据库名; 选择数据库&#xff1a; use 数据库名; 创建表 create table 表名( ); 添加字段&#xff1b; ALTER TABLE 表名 ADD 新字段名 数据类型 [约束条件] [FIRST|AFTER 已存在字段名] ; 删除字段&#xff1a; ALTER TABLE 表…

智慧班牌系统源码,智慧校园云平台系统,基于小程序原生开发的智慧校园小程序源码

智慧班牌系统&#xff0c;也被称为电子班牌系统&#xff0c;是一款专为学校打造的信息化产品&#xff0c;用于加强学校班级文化建设和班级风采展示。该系统通过整合学校对外宣传、日常互动交流、教师教学办公、课外学习延伸、智能硬件接入等各种服务&#xff0c;为老师、家长、…

数据库原理(数据库设计)——(3)

一、数据库设计概述 1.数据库设计的基本任务和目标 基本任务 根据用户的信息需求、数据库操作需求&#xff0c;设计一个结构合理、使用方便、效率高的数据库。 设计目标 满足用户的应用要求&#xff1b;准确模拟现实世界&#xff1b;能背某个DBMS&#xff08;数据库管理系统…

使用超声波麦克风阵列预测数控机床刀具磨损

预测性维护是使用传感器数据来推断机器状态&#xff0c;并从这些传感器数据中检测出在故障发生之前存在的缺陷或故障的过程。预测性维护在所有工业领域都是一种日益增长的趋势&#xff0c;包括轴承故障检测、齿轮磨损检测或往复式机器中的活塞磨损等许多其他例子。在预测性维护…

产品经理的未来在哪里?

【同学聚会】 医生说&#xff1a;你生病的话可以找我。 老师说&#xff1a;你孩子成绩不好时找你辅导。 律师说&#xff1a;你遇上官司时我帮你。 程序员说&#xff1a;你电脑坏了时我帮你修理。 产品经理说&#xff1a;我……好像无一技之长。&#xff08;瞬间开始怀疑人…

Selenium WebDriver - 其它

一、上手 如果您是Selenium的新手&#xff0c;我们有一些资源可以帮助您立即了解最新情况。 Selenium通过使用WebDriver支持市场上所有主要浏览器的自动化。 WebDriver是一种API和协议&#xff0c;它定义了一个语言中立的界面&#xff0c;用于控制Web浏览器的行为。 每个浏览…

PV180R1K1T1NMMC派克通轴传动结构柱塞泵

PV180R1K1T1NMMC派克通轴传动结构柱塞泵 派克柱塞泵的结构组成部分&#xff1a;柱塞、手把、斜盘、压盘、滑履、泵体、配油盘、传送轴。其优点如下&#xff1a; 1、结构紧凑耐用&#xff0c;具有灵活的安装接口 2、安静的工作 3、效率高 4、降低功耗和减少发热 5、具有“…

【C语言】函数指针变量,函数调用函数

这一期文章来通过示例代码说明一下函数指针变量的定义&#xff0c; 主要讲解使用示例代码。(因为确实太干了所以封面凑的) C语言中&#xff0c; 函数指针变量的一般的定义方法是 返回类型 (*指针变量名)(参数列表), 例如 int (*func)(int, int)下面我们定义一个函数&#xff…

最适合程序员的编程字体,漂亮、独特、优雅!(2024-06-17)

Monaco Monaco 字体是一款专为编程和代码编辑设计的等宽字体&#xff0c;以其简洁明了的无衬线设计风格、高可读性和清晰的字符区分度&#xff0c;受到开发者们的青睐&#xff0c;Mac 自带 Monaco 字体。 Consolas Consolas 是一款等宽无衬线字体&#xff0c;专为编程和代码编…

ElementPlus国际化(将组件的默认语言改为中文)

文章目录 1. Element-plus的默认语言2. 编辑 main.js 文件3. 效果&#xff08;以分页条组件为例&#xff09; 1. Element-plus的默认语言 Element-plus的默认语言是英语&#xff0c;可修改为其它语言 2. 编辑 main.js 文件 import {createApp} from vue import ElementPlus …

高等数学笔记(一):映射与函数

一、映射 1.1 映射的概念 存在一个法则 f &#xff0c;使得对 X 中每个元素 x &#xff0c;在 Y 中有唯一确定的元素 y 与之对应&#xff08;X、Y 非空集&#xff09; 称 f 为从 X 到 Y 的映射&#xff0c;如图所示 其中 y 称为元素 x&#xff08;在映射 f 下&#xff09;的…

理解并应用:JavaScript响应式编程与事件驱动编程的差异

背景介绍 在现代JavaScript开发中&#xff0c;响应式编程&#xff08;Reactive Programming&#xff09;和事件驱动编程&#xff08;Event-Driven Programming&#xff09;是两种非常重要且常用的编程范式。虽然它们都用于处理异步操作&#xff0c;但在理念和实现方式上存在显…