Android OkHttp+Retrofit+Rxjava+Hilt 的网络请求封装

今天给大家简单的封装一个现在比较流行的网络请求框架

第一步是导入我们所需要的依赖还需要在android {}闭包下添加一个

buildFeatures{
    viewBinding true
}
implementation "io.reactivex.rxjava2:rxjava:2.2.6" // 必要rxjava依赖
    implementation "io.reactivex.rxjava2:rxandroid:2.1.0" // 必要rxandrroid依赖,切线程时需要用到
    implementation 'com.squareup.retrofit2:retrofit:2.8.1' // 必要retrofit依赖
    implementation 'com.squareup.retrofit2:converter-gson:2.8.1' // 必要依赖,解析json字符所用
    implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0' //非必要依赖,log依赖,如果需要打印OkHttpLog需要添加
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0' // 必要依赖,和rxjava结合必须用到

    implementation 'com.google.dagger:hilt-android:2.40.1'
    annotationProcessor 'com.google.dagger:hilt-compiler:2.40.1'

然后在app下的build.gradle中添加

apply plugin: 'dagger.hilt.android.plugin'

在项目的build.gradle中添加

 repositories {
        google()
        mavenCentral()
    } 
dependencies {
       
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.40.1'
    }
allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

第二步,创建一个network包,然后在包下创建一个NetWorkcarrier 用来先做一个简单的OkHttp+Retrofit的封装

package com.ghn.networkdemo.network;

import com.ghn.networkdemo.utils.Log;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.TrustManager;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 */
public class NetWorkcarrier {
    private static volatile NetWorkcarrier instances;
    private static volatile OkHttpClient okHttpClient;
    private static volatile Retrofit retrofit;

    /**
     * 单例
     * @return
     */
    public static NetWorkcarrier getInstance() {
        if (instances == null) {
            synchronized (NetWorkcarrier.class) {
                if (instances == null) {
                    instances = new NetWorkcarrier();
                }
            }

        }
        return instances;
    }
    private static int TIME_OUT = 30; //30秒超时断开连接

    private OkHttpClient initClient() {
        if (okHttpClient == null) {
            synchronized (NetWorkcarrier.class) {
                if (okHttpClient == null) {
                    //请求日志打印
                    HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(message -> {
                        try {
                            Log.e(URLDecoder.decode(message, "utf-8"));
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                            Log.e(message);
                        }
                    });
                    loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
                    /**
                     * 创建OkHttpClient对象,构建一个网络类型的实例,一般会将所有的网络请求使用同一个单例对象。(如果OkHttpClient使用默认,可不设置)
                     */
                    okHttpClient = new OkHttpClient.Builder()
                            .sslSocketFactory(new NetworkSSL(TrustManager.trustAllCert), TrustManager.trustAllCert)
                            .connectTimeout(TIME_OUT, TimeUnit.SECONDS)
                            .addInterceptor(loggingInterceptor)
                            .readTimeout(TIME_OUT, TimeUnit.SECONDS)
                            .writeTimeout(TIME_OUT, TimeUnit.SECONDS)
                            .build();
                }
            }
        }
        return okHttpClient;
    }
    public Retrofit initRetrofit() {
        if (retrofit == null) {
            synchronized (NetWorkcarrier.class) {
                if (retrofit == null) {
                    /**
                     * 创建Retrofit对象,构建一个网络请求的载体对象,在build的时候有非常多的初始化内容,如设置OkHttpClient、设置请求的url,添加数据转换器等。
                     */
                    retrofit = new Retrofit.Builder()
                            .client(initClient())//选填
                            .baseUrl(Api.BASE_URL)//必填
                            .addConverterFactory(GsonConverterFactory.create())//选填(数据转换器,解析)
                            .build();
                }
            }
        }
        return retrofit;
    }

    public Retrofit initRetrofitRxJava() {
        if (retrofit == null) {
            synchronized (NetWorkcarrier.class) {
                if (retrofit == null) {
                    //注释2:设置Retrofit
                    retrofit = new Retrofit.Builder()
                            .client(initClient())//选填
                            .baseUrl(Api.BASE_URL)//必填
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//新增网络请求适配器
                            .addConverterFactory(GsonConverterFactory.create())//选填(数据转换器,解析)
                            .build();
                }
            }
        }
        return retrofit;
    }
}

这个时候你的代码应该会有三个错误,第一个是Log的错误,另一个是api的错误 、最后一个是NetworkSSL,是因为你还没有我们的代码中对应的类

这个是后你得再创建一个utils包创建一个Log类然后

package com.ghn.networkdemo.utils;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 */
public class Log {
    public static final String TAG_START = "-sc-";
    private Log() {
        /* cannot be instantiated */
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    public static void e(Class<?> cla, String msg) {
        e(cla.getSimpleName(), msg);
    }

    public static void e(String msg) {
        android.util.Log.e(TAG_START, msg + "");
    }
    public static void e(String tag, String msg) {
        android.util.Log.e(TAG_START + tag, msg + "");
    }
}

然后在我们的network中创建一个api包和在包里创建一个Api的接口类,不过在创建这个Api接口类之前我们要先创建一个统一的接口后台返回的结果的类,然后在network中创建一个data的包,包下创建一个ResponseData类,里面写我们的统一返回的的数据,这个是和后端的接口是保持一至的

package com.ghn.networkdemo.data;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 *统一接收后台返回的数据
 */
public class ResponseData<T> {
    private int errorCode;
    private String errorMsg;
    private T data;

    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}
package com.ghn.networkdemo.Api;
import com.ghn.networkdemo.bean.BannerBean;
import com.ghn.networkdemo.data.ResponseData;

import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 */
public interface Api {
    String BASE_URL = "https://www.wanandroid.com/";
    //OkHttp+Retrofit
    @GET("banner/json")
    Call<ResponseData<List<BannerBean>>> BannerRetrofit();
}

然后再来创建一个NetworkSSL的类和TrustManager的类和我们的NetworkModule类

package com.ghn.networkdemo.network;

import android.os.Build;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 */
public class NetworkSSL extends SSLSocketFactory {
    private SSLSocketFactory defaultFactory;
    static String protocols[] = null, cipherSuites[] = null;

    static {
        try {
            SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
            if (socket != null) {
                List<String> protocols = new LinkedList<>();
                for (String protocol : socket.getSupportedProtocols())
                    if (!protocol.toUpperCase().contains("SSL"))
                        protocols.add(protocol);
                NetworkSSL.protocols = protocols.toArray(new String[protocols.size()]);
                /* set up reasonable cipher suites */
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                    // choose known secure cipher suites
                    List<String> allowedCiphers = Arrays.asList(
                            // TLS 1.2
                            "TLS_RSA_WITH_AES_256_GCM_SHA384",
                            "TLS_RSA_WITH_AES_128_GCM_SHA256",
                            "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
                            "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
                            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
                            "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
                            "TLS_ECHDE_RSA_WITH_AES_128_GCM_SHA256",
                            // maximum interoperability
                            "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
                            "TLS_RSA_WITH_AES_128_CBC_SHA",
                            // additionally
                            "TLS_RSA_WITH_AES_256_CBC_SHA",
                            "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
                            "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
                            "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
                            "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
                    List<String> availableCiphers = Arrays.asList(socket.getSupportedCipherSuites());
                    HashSet<String> preferredCiphers = new HashSet<>(allowedCiphers);
                    preferredCiphers.retainAll(availableCiphers);
                    HashSet<String> enabledCiphers = preferredCiphers;
                    enabledCiphers.addAll(new HashSet<>(Arrays.asList(socket.getEnabledCipherSuites())));
                    NetworkSSL.cipherSuites = enabledCiphers.toArray(new String[enabledCiphers.size()]);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public NetworkSSL(X509TrustManager tm) {
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, (tm != null) ? new X509TrustManager[]{tm} : null, null);
            defaultFactory = sslContext.getSocketFactory();
        } catch (GeneralSecurityException e) {
            throw new AssertionError(); // The system has no TLS. Just give up.
        }
    }

    private void upgradeTLS(SSLSocket ssl) {
        if (protocols != null) {
            ssl.setEnabledProtocols(protocols);
        }
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && cipherSuites != null) {
            ssl.setEnabledCipherSuites(cipherSuites);
        }
    }
    @Override
    public String[] getDefaultCipherSuites() {
        return cipherSuites;
    }
    @Override
    public String[] getSupportedCipherSuites() {
        return cipherSuites;
    }
    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        Socket ssl = defaultFactory.createSocket(s, host, port, autoClose);
        if (ssl instanceof SSLSocket) {
            upgradeTLS((SSLSocket) ssl);
        }
        return ssl;
    }
    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        Socket ssl = defaultFactory.createSocket(host, port);
        if (ssl instanceof SSLSocket) {
            upgradeTLS((SSLSocket) ssl);
        }
        return ssl;
    }
    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        Socket ssl = defaultFactory.createSocket(host, port, localHost, localPort);
        if (ssl instanceof SSLSocket) {
            upgradeTLS((SSLSocket) ssl);
        }
        return ssl;
    }
    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        Socket ssl = defaultFactory.createSocket(host, port);
        if (ssl instanceof SSLSocket) {
            upgradeTLS((SSLSocket) ssl);
        }
        return ssl;
    }
    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        Socket ssl = defaultFactory.createSocket(address, port, localAddress, localPort);
        if (ssl instanceof SSLSocket) {
            upgradeTLS((SSLSocket) ssl);
        }
        return ssl;
    }
}
package com.ghn.networkdemo.network;

import java.security.cert.CertificateException;

import javax.net.ssl.X509TrustManager;

/**
 * @author 浩楠
 * @date 2022/8/510:56.
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 */
public class TrustManager {
    public static X509TrustManager trustAllCert = new X509TrustManager() {
        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[]{};
        }
    };
}
package com.ghn.networkdemo.network;

import com.ghn.networkdemo.network.Api.Api;
import com.ghn.networkdemo.utils.Log;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
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;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 *
 */
@InstallIn(SingletonComponent.class)
@Module
public class NetworkModule {
    private static int TIME_OUT = 30; //30秒超时断开连接
    @Provides
    @Singleton
    public OkHttpClient providesOkHttpClient(){
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                try {
                    Log.e("--network--", URLDecoder.decode(message, "utf-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    Log.e("--network--", message);
                }
            }
        });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return new OkHttpClient.Builder()
                .sslSocketFactory(new NetworkSSL(TrustManager.trustAllCert), TrustManager.trustAllCert)
                .connectTimeout(TIME_OUT, TimeUnit.SECONDS)
                .addInterceptor(loggingInterceptor)
                .readTimeout(TIME_OUT, TimeUnit.SECONDS)
                .writeTimeout(TIME_OUT, TimeUnit.SECONDS)
                .build();
    }
    @Singleton
    @Provides
    public Retrofit providesRetrofit(OkHttpClient okHttpClient){
        return new Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(Api.BASE_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    @Singleton
    @Provides
    public Api providesWanAndroidService(Retrofit retrofit){
        return retrofit.create(Api.class);
    }
}

第三步:创建一个统一异常处理的类ApiException和ErrorConsumer 类

package com.ghn.networkdemo.network;

import android.net.ParseException;

import com.google.gson.JsonParseException;

import org.json.JSONException;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 * 统一的异常处理
 */
public class ApiException extends Exception{
    public static final int UNKNOWN = 1000;
    public static final int PARSE_ERROR = 1001;
    public static final int NETWORK_ERROR = 1002;
    private int code;
    private String displayMessage;

    public ApiException(int code, String displayMessage) {
        this.code = code;
        this.displayMessage = displayMessage;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getDisplayMessage() {
        return displayMessage;
    }

    public void setDisplayMessage(String displayMessage) {
        this.displayMessage = displayMessage;
    }

    public static ApiException handleException(Throwable e) {
        ApiException ex;
        if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {
            //解析错误
            ex = new ApiException(PARSE_ERROR, e.getMessage());
            return ex;
        } else if (e instanceof ConnectException) {
            //网络错误
            ex = new ApiException(NETWORK_ERROR, e.getMessage());
            return ex;
        } else if (e instanceof UnknownHostException || e instanceof SocketTimeoutException) {
            //连接错误
            ex = new ApiException(NETWORK_ERROR, e.getMessage());
            return ex;
        } else {
            //未知错误
            ex = new ApiException(UNKNOWN, e.getMessage());
            return ex;
        }
    }
}
package com.ghn.networkdemo.network;

import org.jetbrains.annotations.NotNull;

import io.reactivex.functions.Consumer;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 *统一的异常处理实现Consumer<Throwable>接口
 */
public abstract class ErrorConsumer implements Consumer<Throwable> {
    @Override
    public void accept(@NotNull Throwable throwable) throws Exception {
        //对异常进行处理
        ApiException exception;
        if (throwable instanceof ApiException) {
            exception = (ApiException) throwable;
        } else {
            exception = ApiException.handleException(throwable);
        }
        //调用error方法
        error(exception);
    }
    //使用时实现error方法即可。
    protected abstract void error(ApiException e);
}

第四步:对响应进行转换处理

package com.ghn.networkdemo.network;

import com.ghn.networkdemo.data.ResponseData;

import org.jetbrains.annotations.NotNull;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 */
public class ResponseTransformer<T> implements ObservableTransformer<ResponseData<T>, T> {
    public ResponseTransformer() {
    }

    public static <R> ResponseTransformer<R> obtain() {
        return new ResponseTransformer<>();
    }

    @NotNull
    @Override
    public ObservableSource<T> apply(@NotNull Observable<ResponseData<T>> upstream) {
        return upstream.onErrorResumeNext(new Function<Throwable, ObservableSource<? extends ResponseData<T>>>() {
            @Override
            public ObservableSource<? extends ResponseData<T>> apply(@NotNull Throwable throwable) throws Exception {
                return Observable.error(ApiException.handleException(throwable));
            }
        }).flatMap(new Function<ResponseData<T>, ObservableSource<T>>() {
            @Override
            public ObservableSource<T> apply(@NotNull ResponseData<T> responseData) throws Exception {
                //请求成功
                if (0 == responseData.getErrorCode()) {
                    return Observable.just(responseData.getData());
                }
                //请求异常
                return Observable.error(new ApiException(responseData.getErrorCode(), responseData.getErrorMsg()));
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }
}

第五步:对Hilt进行添加,我们需要对我们的Application添加一个@HiltAndroidApp 的注解,所以我们要在主包下面创建一个app类才继承我们的Application添加注解并且在我们的清单文件中的name中添加我们新建的app类

package com.ghn.networkdemo;

import android.app.Application;

import dagger.hilt.android.HiltAndroidApp;

/**
 * @author 浩楠
 * @date 2022/8/5
 * <p>
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 */
@HiltAndroidApp
public class App extends Application { }
  <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AndroidDemo">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

最后我们来使用一下我们的这个网络请求

因为我们的接口是banner的接口,我们就不写轮播图了就写一个textview展示一下我们的网络请求的数据就好,

package com.ghn.networkdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.ghn.networkdemo.data.ResponseData;
import com.ghn.networkdemo.databinding.ActivityMainBinding;
import com.ghn.networkdemo.network.Api.Api;
import com.ghn.networkdemo.network.ApiException;
import com.ghn.networkdemo.network.ErrorConsumer;
import com.ghn.networkdemo.network.NetWorkcarrier;
import com.ghn.networkdemo.network.ResponseTransformer;
import com.ghn.networkdemo.network.bean.BannerBean;
import com.ghn.networkdemo.utils.Log;
import com.youth.banner.Banner;
import com.youth.banner.adapter.BannerImageAdapter;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import dagger.hilt.android.AndroidEntryPoint;
import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
    ActivityMainBinding binding;
    private TextView text;
    @Inject
    Api api;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        text = findViewById(R.id.text_view);
        initData();
    }

    private void initData() {
        api.BannerRetrofit()
                .compose(ResponseTransformer.obtain())
                .subscribe(new Consumer<List<BannerBean>>() {
                    @Override
                    public void accept(List<BannerBean> homeBanners) throws Exception {
                        //请求成功
                        if (homeBanners != null) {
                            text.setText(homeBanners.toString());
                        }
                    }
                }, new ErrorConsumer() {
                    @Override
                    protected void error(ApiException e) {
                        //请求失败
                        Log.e(e.getDisplayMessage() + e.getCode());
                    }
                });
    }

}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text_view"
        android:layout_margin="20dp"
        />
</LinearLayout>

最终效果

源码地址

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值