项目的网络请求开发中retrofit2和okhttp3的结合使用示例

2023-12-15 14:58

本文主要是介绍项目的网络请求开发中retrofit2和okhttp3的结合使用示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文是retrofit2和okhttp3的结合使用的简单示例,逻辑不复杂,示例代码中使用的框架版本是okhttp:4.4.0和retrofit:2.7.2,下文将贴出所有代码:

项目结构:

AndroidManifest的配置: 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.windfallsheng.retrofitandokhttpexample"><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission><uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission><uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission><!--用于访问网络--><uses-permission android:name="android.permission.INTERNET"></uses-permission><applicationandroid:name=".MySupportApplication"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/AppTheme"><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>

build.gradle的配置内容:

apply plugin: 'com.android.application'android {compileSdkVersion 28defaultConfig {applicationId "com.windfallsheng.retrofitandokhttpexample"minSdkVersion 16targetSdkVersion 28versionCode 1versionName "1.0"testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
}dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'com.android.support:appcompat-v7:28.0.0'implementation 'com.android.support.constraint:constraint-layout:1.1.3'testImplementation 'junit:junit:4.12'androidTestImplementation 'com.android.support.test:runner:1.0.2'androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'// 加入依赖implementation "com.squareup.okhttp3:okhttp:4.4.0"implementation "com.squareup.okhttp3:logging-interceptor:4.4.0"implementation "com.squareup.retrofit2:retrofit:2.7.2"implementation "com.squareup.retrofit2:converter-gson:2.7.2"implementation "com.google.code.gson:gson:2.8.6"
}

 使用:

package com.windfallsheng.retrofitandokhttpexample;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.windfallsheng.retrofitandokhttpexample.net.Param;
import com.windfallsheng.retrofitandokhttpexample.net.ResponseEntity;
import com.windfallsheng.retrofitandokhttpexample.net.RetrofitManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;public class MainActivity extends AppCompatActivity {private static final String TAG = MainActivity.class.getSimpleName();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 设置请求参数的过程;List<Param> paramList = new ArrayList<>();paramList.add(new Param("sex", "0"));paramList.add(new Param("age", "25"));Map paramMap = new HashMap();for (Param param : paramList) {paramMap.put(param.getKey(), param.getValue());}Call call = RetrofitManager.getDefault(ServerHost.USER_INFO).getUserList(RetrofitManager.getCacheControl(), paramMap);// 开始网络请求:call.enqueue(new Callback<ResponseEntity>() {@Overridepublic void onResponse(retrofit2.Call<ResponseEntity> call, Response<ResponseEntity> response) {Log.d(TAG, "method:login#onResponse#response.isSuccessful=" + response.isSuccessful());if (response.isSuccessful()) {Log.d(TAG, "method:login#onResponse#ResponseEntity=" + response.body());}}@Overridepublic void onFailure(retrofit2.Call call, Throwable t) {Log.d(TAG, "method:login#onFailure#t=" + t);}});}
}

接口定义:

package com.windfallsheng.retrofitandokhttpexample.net;import android.database.Observable;
import java.util.Map;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.Header;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.PartMap;/*** @author lzsheng 请求接口;*/
public interface APIService {@FormUrlEncoded@POST("mobileuser/login")Observable<ResponseEntity> login(@Header("Cache-Control") String cacheControl, @Field("phoneNumber") String account,@Field("password") String password);@Multipart@POST("mobileuser/register")Observable<ResponseEntity> registe(@PartMap Map<String, RequestBody> multipartMap);@FormUrlEncoded@POST("mobileuser/userlist")Call<ResponseEntity> getUserList(@Header("Cache-Control") String cacheControl, @FieldMap Map<String, String> params);}

网络请求及初始化配置管理类:

package com.windfallsheng.retrofitandokhttpexample.net;import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.windfallsheng.retrofitandokhttpexample.MySupportApplication;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;/*** 缓存设置* 1. noCache 不使用缓存,全部走网络* 2. noStore 不使用缓存,也不存储缓存* 3. onlyIfCached 只使用缓存* 4. maxAge 设置最大失效时间,失效则不使用 需要服务器配合* 5. maxStale 设置最大失效时间,失效则不使用 需要服务器配合* 6. minFresh 设置有效时间,依旧如上* 7. FORCE_NETWORK 只走网络* 8. FORCE_CACHE 只走缓存*/
public class RetrofitManager {private static final String TAG = "RetrofitManager";//读超时长,单位:毫秒public static final int READ_TIME_OUT = 7676;//连接时长,单位:毫秒public static final int CONNECT_TIME_OUT = 7676;public Retrofit mRetrofit;public APIService mAPIService;public OkHttpClient mOkHttpClient;private static SparseArray<RetrofitManager> sRetrofitManager = new SparseArray<>(ServerHost.values().length);/*** 设缓存有效期为两天*/private static final long CACHE_STALE_SEC = 60 * 60 * 24 * 2;/*** 查询缓存的Cache-Control设置,为if-only-cache时只查询缓存而不会请求服务器,max-stale可以配合设置缓存失效时间* max-stale 指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可接收超出超时期指定值之内的响应消息。*/private static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC;/*** 查询网络的Cache-Control设置,头部Cache-Control设为max-age=0* (假如请求了服务器并在a时刻返回响应结果,则在max-age规定的秒数内,浏览器将不会发送对应的请求到服务器,数据由缓存直接返回)时则不会使用缓存而请求服务器*/private static final String CACHE_CONTROL_AGE = "max-age=0";//构造方法私有private RetrofitManager(String baseUrl) {//开启LogHttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);//缓存File cacheFile = new File(MySupportApplication.getInstance().getCacheDir(), "cache");Cache cache = new Cache(cacheFile, 1024 * 1024 * 100); //100Mb//增加头部信息Interceptor headerInterceptor = new Interceptor() {@Overridepublic Response intercept(Chain chain) throws IOException {Request build = chain.request().newBuilder().addHeader("Content-Type", "application/json").build();return chain.proceed(build);}};mOkHttpClient = new OkHttpClient.Builder().readTimeout(READ_TIME_OUT, TimeUnit.MILLISECONDS).connectTimeout(CONNECT_TIME_OUT, TimeUnit.MILLISECONDS).addInterceptor(mRewriteCacheControlInterceptor).addNetworkInterceptor(mRewriteCacheControlInterceptor).addInterceptor(headerInterceptor).addInterceptor(logInterceptor).cache(cache).build();Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").serializeNulls().create();mRetrofit = new Retrofit.Builder().client(mOkHttpClient).addConverterFactory(GsonConverterFactory.create(gson))
//                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()).baseUrl(baseUrl).build();mAPIService = mRetrofit.create(APIService.class);}/*** @param serverHost {@link ServerHost}*/public static APIService getDefault(ServerHost serverHost) {Log.d(TAG, "method:getDefault#sRetrofitManager=" + sRetrofitManager);int hostType = serverHost.getHostType();RetrofitManager retrofitManager = sRetrofitManager.get(hostType);if (retrofitManager == null) {retrofitManager = new RetrofitManager(serverHost.getBaseUrl());sRetrofitManager.put(hostType, retrofitManager);}return retrofitManager.mAPIService;}/*** OkHttpClient** @return*/public static OkHttpClient getOkHttpClient(ServerHost serverHost) {int hostType = serverHost.getHostType();String baseUrl = serverHost.getBaseUrl();RetrofitManager retrofitManager = sRetrofitManager.get(hostType);if (retrofitManager == null) {retrofitManager = new RetrofitManager(baseUrl);sRetrofitManager.put(hostType, retrofitManager);}return retrofitManager.mOkHttpClient;}/*** 根据网络状况获取缓存的策略*/public static String getCacheControl() {return isNetworkAvailable(MySupportApplication.getInstance()) ? CACHE_CONTROL_AGE : CACHE_CONTROL_CACHE;}/*** 响应头拦截器,用来配置缓存策略* Dangerous interceptor that rewrites the server's cache-control header.*/private final Interceptor mRewriteCacheControlInterceptor = new Interceptor() {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();String cacheControl = request.cacheControl().toString();if (!isNetworkAvailable(MySupportApplication.getInstance())) {request = request.newBuilder().cacheControl(TextUtils.isEmpty(cacheControl) ? CacheControl.FORCE_NETWORK : CacheControl.FORCE_CACHE).build();}Response originalResponse = chain.proceed(request);if (isNetworkAvailable(MySupportApplication.getInstance())) {//有网的时候读接口上的@Headers里的配置,你可以在这里进行统一的设置return originalResponse.newBuilder().header("Cache-Control", cacheControl).removeHeader("Pragma").build();} else {return originalResponse.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + CACHE_STALE_SEC).removeHeader("Pragma").build();}}};private static boolean isNetworkAvailable(Context context) {ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);if (connectivity != null) {//ACCESS_NETWORK_STATENetworkInfo info = connectivity.getActiveNetworkInfo();if (info != null && info.isConnected()) {// 当前网络是连接的if (info.getState() == NetworkInfo.State.CONNECTED) {// 当前所连接的网络可用return true;}}}return false;}}

 定义各host的枚举类:

package com.windfallsheng.retrofitandokhttpexample.net;/*** @author lzsheng host的枚举;*/
public enum ServerHost {USER_INFO(1, "http://192.*.*.*:8066/"), NEWS_FLASH(2, "https://192.*.*.*:8080/");private int hostType;private String baseUrl;private ServerHost(int type, String baseUrl) {this.hostType = type;this.baseUrl = baseUrl;}public int getHostType() {return hostType;}public void setHostType(int hostType) {this.hostType = hostType;}public String getBaseUrl() {return baseUrl;}public void setBaseUrl(String baseUrl) {this.baseUrl = baseUrl;}
}

其它相关类:

package com.windfallsheng.retrofitandokhttpexample;import android.app.Application;
import android.content.Context;public class MySupportApplication extends Application {private static Context mContext;@Overridepublic void onCreate() {super.onCreate();mContext = this;}public static Context getInstance() {return mContext;}
}
package com.windfallsheng.retrofitandokhttpexample.net;import com.google.gson.annotations.SerializedName;
import java.io.Serializable;/*** @Author: lzsheng* @Description: 网络请求的返回值实体类, 使用新版本Gson的jar包,修改注解 @SerializedName(value = "val",* alternate = {"alt1", "alt2"})* @Version:*/
public class ResponseEntity<T> implements Serializable {@SerializedName(value = "code", alternate = {"rt", "result"})private int resultCode;@SerializedName("success")private boolean isSuccess;@SerializedName(value = "msg", alternate = {"message", "content"})private String resultMsg;private T data;public int getResultCode() {return resultCode;}public void setResultCode(int resultCode) {this.resultCode = resultCode;}public boolean isSuccess() {return isSuccess;}public void setSuccess(boolean success) {isSuccess = success;}public String getResultMsg() {return resultMsg;}public void setResultMsg(String resultMsg) {this.resultMsg = resultMsg;}public T getData() {return data;}public void setData(T data) {this.data = data;}@Overridepublic String toString() {return "ResponseEntity{" +"resultCode=" + resultCode +", isSuccess=" + isSuccess +", resultMsg='" + resultMsg + '\'' +", data=" + data +'}';}
}
package com.windfallsheng.retrofitandokhttpexample.net;/*** @author lzsheng 请求参数的键值对*/
public class Param {private String key;private String value;public Param() {}public Param(String key, String value) {super();this.key = key;this.value = value;}public String getKey() {return key;}public void setKey(String key) {this.key = key;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}@Overridepublic String toString() {return "Param [key=" + key + ", value=" + value + "]";}}

       有关网络请求相关业务的处理方式多种多样,根据自己的项目状态和业务需求,做相应的业务封闭即可,以上只是简单演示,不必苛责。

 

由于作者水平有限,语言描述及代码实现中难免有纰漏,望各位看官多提宝贵意见!

Hello , World !

感谢所有!

这篇关于项目的网络请求开发中retrofit2和okhttp3的结合使用示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面