项目的网络请求开发中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

相关文章

MySQL 主从复制部署及验证(示例详解)

《MySQL主从复制部署及验证(示例详解)》本文介绍MySQL主从复制部署步骤及学校管理数据库创建脚本,包含表结构设计、示例数据插入和查询语句,用于验证主从同步功能,感兴趣的朋友一起看看吧... 目录mysql 主从复制部署指南部署步骤1.环境准备2. 主服务器配置3. 创建复制用户4. 获取主服务器状态5

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定