Retrofit本身并不支持网络通讯。

Retrofit封装了OkHttp,让网络请求更加简单。

Retrofit通过接口+注解的方式,封装了重复的代码。

封装了Gson,可以直接将返回的json字符串转换成Java对象

结合rxjava,实现响应式编程

使用Retrofit进行网络通讯就好像使用SpringCloud中的Openfeign

官网地址:https://square.github.io/retrofit/

使用步骤

准备

1、在build.gradle中引入依赖implementation 'com.squareup.retrofit2:retrofit:2.9.0'

2、在AndroidManifest.xml中添加网络请求权限<uses-permission android:name="android.permission.INTERNET"/>

一、简单使用

使用 https://www.httpbin.org/ 作为我们的测试接口地址

1、创建接口类

@POST 声明为post请求,实际请求地址会拼接成 https://www.httpbin.org/post, 通过@FormUrlEncoded和@Field声明表单请求参数;@Body声明Body参数。

@GET 声音为get请求,实际请求地址会拼接成 https://www.httpbin.org/get, 通过@Query声明请求参数。

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;public interface HttpbinService {@POST("post")@FormUrlEncodedCall<ResponseBody> post(@Field("username") String username, @Field("password")  String pwd);@GET("get")Call<ResponseBody> get(@Query("username") String username,@Query("password")  String pwd);@POST("post")Call<ResponseBody> postBody(@Body RequestBody requestBody);
}

2、在Android程序中使用

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;public class MainActivity extends AppCompatActivity {private Retrofit retrofit;private HttpbinService httpbinService;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);retrofit = new Retrofit.Builder().baseUrl("https://www.httpbin.org/").build();httpbinService = retrofit.create(HttpbinService.class);}/*** 异步Get请求*/public void getAsync(View view) {Call<ResponseBody> resp = httpbinService.get("test", "123123");resp.enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {try {Log.d("test", "getAsync: " + response.body().string());} catch (IOException e) {e.printStackTrace();}}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {Log.d("test", "getAsync error: " + t.getMessage());}});}/*** 异步Post请求*/public void postAsync(View view) {Call<ResponseBody> resp = httpbinService.post("test", "123123");resp.enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {try {Log.d("test", "postAsync: " + response.body().string());} catch (IOException e) {e.printStackTrace();}}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {Log.d("test", "postAsync error: " + t.getMessage());}});}}

二、配合Gson 以及 Rxjava,返回java对象和响应式编程

在build.gradle中引入依赖

implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'

本例中使用 https://www.wanandroid.com/ 测试接口调用

1、添加测试接口类

import io.reactivex.rxjava3.core.Flowable;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;public interface WanAndroidTestService {/**正常返回 Java对象 */@POST("/user/login")@FormUrlEncodedCall<LoginUser> login(@Field("username") String username, @Field("password") String password);/**通过RxJava响应式返回 Java对象 */@POST("/user/login")@FormUrlEncodedFlowable<LoginUser> login2(@Field("username") String username, @Field("password") String password);/**通过RxJava响应式返回 ResponseBody */@GET("lg/collect/list/{pageNum}/json")Flowable<ResponseBody> getArticle(@Path("pageNum") int pageNum);
}

2、测试使用,返回Java对象

添加转换器 addConverterFactory(GsonConverterFactory.create())

public class WanAndroidUnitTest {Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.wanandroid.com/").addConverterFactory(GsonConverterFactory.create())//添加转换器.build();WanAndroidTestService wanAndroidService = retrofit.create(WanAndroidTestService.class);@Testpublic void login() throws IOException {Response<LoginUser> response = wanAndroidService.login("xxxxx", "xxxxx").execute();LoginUser loginUser = response.body();System.out.println("loginUser = " + loginUser);}
}

3、配合RxJava使用,并使用cookie

添加Cookie支持
添加Gson转换器addConverterFactory(GsonConverterFactory.create())
添加RxJava适配器addCallAdapterFactory(RxJava3CallAdapterFactory.create())

本示例代码使用www.wanandroid.com的开放接口,可以自行去注册一个账号用于测试

import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;public class RetrofitCookieUnitTest {Map<String, List<Cookie>> cookies = new HashMap<>();Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.wanandroid.com/")// 添加Cookie支持.callFactory(new OkHttpClient.Builder().cookieJar(new CookieJar() {@Overridepublic void saveFromResponse(HttpUrl url, List<Cookie> list) {cookies.put(url.host(), list);}@Overridepublic List<Cookie> loadForRequest(HttpUrl url) {List<Cookie> list = cookies.get(url.host());return list == null ? new ArrayList<>() : list;}}).build())//添加Gson转换器.addConverterFactory(GsonConverterFactory.create())//添加RxJava适配器.addCallAdapterFactory(RxJava3CallAdapterFactory.create()).build();WanAndroidTestService androidTestService = retrofit.create(WanAndroidTestService.class);@Testpublic void rxTest() throws IOException {androidTestService.login2("xxxxx", "xxxxx")// 登录成功后,执行下一步操作,查询收藏文章列表.flatMap(new Function<LoginUser, Publisher<ResponseBody>>() {@Overridepublic Publisher<ResponseBody> apply(LoginUser loginUser) throws Throwable {return androidTestService.getArticle(0);}}).observeOn(Schedulers.io())// 如果是Android环境需要切换到Android的主线程// .subscribeOn(AndroidSchedulers.mainThread())// 这里是Junit,切换到新的线程.subscribeOn(Schedulers.newThread())// 订阅返回结果,并打印输出.subscribe(new Consumer<ResponseBody>() {@Overridepublic void accept(ResponseBody responseBody) throws Throwable {System.out.println(responseBody.string());}});while (true) {}}
}

4、文件上传、下载

文件上传

使用注解@Multipart@Part实现文件上传

1)创建请求接口

import okhttp3.MultipartBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;public interface UploadFileService {@POST("post")@MultipartCall<ResponseBody> upload(@Part MultipartBody.Part part);
}

2)编写测试代码

public class UploadFileTest {Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.httpbin.org/").build();UploadFileService uploadFileService = retrofit.create(UploadFileService.class);@Testpublic void upload() throws IOException {File file1 = new File("d:/temp/1.txt");MultipartBody.Part part = MultipartBody.Part.createFormData("file1", file1.getName(),RequestBody.create(MediaType.parse("text/plain"), file1));Call<ResponseBody> resp = uploadFileService.upload(part);System.out.println("resp = " + resp.execute().body().string());}
}

文件下载

  • Call 常规下载
  • Flowable 通过RxJava方式下载,需要添加RxJava适配器

如果下载的文件很大,需要增加注解 @Streaming避免出现内存溢出

1)创建请求接口

import io.reactivex.rxjava3.core.Flowable;
import okhttp3.MultipartBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.Streaming;
import retrofit2.http.Url;public interface UploadFileService {@POST("post")@MultipartCall<ResponseBody> upload(@Part MultipartBody.Part part);@GETCall<ResponseBody> download(@Url String url);@Streaming@GETFlowable<ResponseBody> downloadRxJava(@Url String url);
}

2)创建测试用例

import org.junit.Test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;
import okhttp3.ResponseBody;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;public class DownloadFileTest {Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.httpbin.org/")//添加RxJava适配器.addCallAdapterFactory(RxJava3CallAdapterFactory.create()).build();UploadFileService uploadFileService = retrofit.create(UploadFileService.class);@Testpublic void download() throws IOException {Response<ResponseBody> response = uploadFileService.download("https://www.dasouji.com/wp-content/uploads/2020/12/@ukwanghyun.jpg").execute();if (!response.isSuccessful()) {System.out.println("下载失败," + response.code());return;}InputStream inputStream = response.body().byteStream();FileOutputStream fos = new FileOutputStream("d:/temp/3.jpg");int len;byte[] buffer = new byte[4096];while ((len = inputStream.read(buffer)) != -1) {fos.write(buffer, 0, len);}fos.close();inputStream.close();System.out.println("下载完成," + response.code());}@Testpublic void downloadRxJava() throws IOException {uploadFileService.downloadRxJava("https://www.dasouji.com/wp-content/uploads/2020/12/@ukwanghyun.jpg")// 将结果映射成File对象.map(new Function<ResponseBody, File>() {@Overridepublic File apply(ResponseBody responseBody) throws Throwable {InputStream inputStream = responseBody.byteStream();File file = new File("d:/temp/4.jpg");FileOutputStream fos = new FileOutputStream(file);int len;byte[] buffer = new byte[4096];while ((len = inputStream.read(buffer)) != -1) {fos.write(buffer, 0, len);}fos.close();inputStream.close();System.out.println("下载完成!");return file;}})// 获取下载结果.subscribe(new Consumer<File>() {@Overridepublic void accept(File file) throws Throwable {System.out.println("获取下载文件!" + file.getName());}});while (true) {}}
}

Retrofit的注解

  • 方法注解:@GET,@POST,@PUT,@DELETE,@PATH,@HEAD,@OPTIONS,@HTTP
  • 标记注解:@FormUrlEncoded,@Multipart,@Streaming
  • 参数注解:@Query,@Field,@Body,@FieldMap,@QueryMap,@Part,@PartMap
  • 其他注解:@Path,@Header,@Headers,@Url

Android网络通讯之Retrofit相关推荐

  1. Android 网络框架之Retrofit源码解析,flutter边框特效

    Retrofit的构建使用了建造者模式,这个模式的优点就是可以构造复杂的对象,方便扩展,并且看起来代码比较简洁,美观: 在开始之前,我们先来看一下Retrofit的成员变量: 这里的变量并不是很多,我 ...

  2. Android 网络请求库Retrofit简单使用

    载请标明出处: http://blog.csdn.net/u011974987/article/details/50895633: 什么是 Retrofit ? Retrofit 是一套 RESTfu ...

  3. Android网络通讯之OkHttp

    OkHttp是安卓上常用的网络请求框架,不止可以发送http请求,还可以发送socket请求等. 内置了连接池,减少了请求延迟 支持缓存,减少重复的网络请求 支持Cookie存储 支持拦截器,可以对不 ...

  4. Android网络开发之Retrofit+OkHttpClient+RXJava 基本用法演示

    写本文的目的只是为了给需要帮助的朋友提供一个演示,也是记录一下使用这些流行库的基本用法,以便日后用到的时候可以及时找到. 好了,进入正题,关于这三个库的介绍我就不说了,自己百度,先看程序执行效果图: ...

  5. Android设备上使用WiFinspect抓取网络通讯包

    之前的文章我们介绍过使用Fiddler来抓取Android设备通信HTPP,  今天我们需要更加细节网络抓包. 首先, 您的Andriod设备需要root权限, 去Google Play安装一个叫Wi ...

  6. Android网络库的比较:OkHTTP,Retrofit和Volley [关闭]

    本文翻译自:Comparison of Android networking libraries: OkHTTP, Retrofit, and Volley [closed] Two-part que ...

  7. Android网络请求框架之Retrofit(二)

    前面一篇文章介绍了Retrofit的基本用法,没有看过的童鞋可以移步:Android网络请求框架之Retrofit(一),现在我们来继续介绍Retrofit配合RxJava.RxAndroid的用法. ...

  8. Android之全面解析Retrofit网络框架封装库

    转载请标明出处:[顾林海的博客] 前言 Retrofit是Square公司推出的一个HTTP的框架,主要用于Android和Java,Retrofit会将每一个HTTP的API请求变成一个Java的接 ...

  9. android socket 发送byte_如何正确地创建和销毁网络通讯程序中的Socket类的对象实例...

    软件项目实训及课程设计指导--如何正确地创建和销毁软件应用系统中网络通讯中的Socket类的对象实例 1.基于TCP/IP协议的Socket通信相关的基础知识 (1)TCP/IP(Transmissi ...

  10. Android网络编程系列 一 Socket抽象层

    在<Android网络编程>系列文章中,前面已经将Java的通信底层大致的描述了,在我们了解了TCP/IP通信族架构及其原理,接下来我们就开始来了解基于tcp/ip协议层的Socket抽象 ...

最新文章

  1. SElinux测试及排错
  2. String insert()总结
  3. [Linux]控制语句If case
  4. html5元素拖动 (转载黑桐)
  5. JAVA设计模式--辛格尔顿
  6. 十四个方法提高博客的页面访问量
  7. android view setleft,android – 在新textview上使用setLeft / setRight方法
  8. 效率源希捷硬盘远程维修案例-K9K10盘写认流程
  9. Visual C# .NET2003语言的改变
  10. Spring中Bean的作用域/状态/生命周期
  11. oracle禁止访问监听,关于ORACLE数据库监听自动停止解决一例
  12. a站、b站、c站、d站、e站、f站、g站、h站、i站、j站、k站、l站、m站、n站…z站?
  13. 深圳免费旅游景点大全|深圳旅游攻略(下)
  14. anaconda安装包
  15. LOJ 3124 「CTS2019 | CTSC2019」氪金手游——概率+树形DP
  16. python 字典的常见方法
  17. laravel框架搭建voyager
  18. [Substrate Recipes翻译]1.21 Tightly- and Loosely-Coupled Pallets
  19. R语言统计分析|批量单变量Cox回归分析
  20. STM32——继电器控制灯的开关

热门文章

  1. conda创建管理虚拟环境
  2. 查询IP所在区段(C#)
  3. iphone和ipad的一些区别
  4. ipad、iphone 怎么真机调试
  5. 1G、2G、3G、4G和5G有什么区别?5G的原理是什么?
  6. transformer变体
  7. C#实现来电显示功能
  8. 一个智能家居“适老化”的准样本
  9. 小程序毕业设计选题springboot+vue自习室预约小程序 图书馆预约小程序 自习室预约系统java
  10. Linux学习-账户管理