在本文中,我们将给您介绍关于在Android中使用Retrofit的简单GET请求的详细内容,并且为您解答androidretrofit原理的相关问题,此外,我们还将为您提供关于AndroidOkHt
在本文中,我们将给您介绍关于在 Android 中使用 Retrofit 的简单 GET 请求的详细内容,并且为您解答android retrofit原理的相关问题,此外,我们还将为您提供关于Android OkHttp + Retrofit 取消请求的方法、android okhttp + retrofit使用、Android Retrofit 2.0 使用-补充篇、Android Retrofit 2.5.0使用基础详解的知识。
本文目录一览:- 在 Android 中使用 Retrofit 的简单 GET 请求(android retrofit原理)
- Android OkHttp + Retrofit 取消请求的方法
- android okhttp + retrofit使用
- Android Retrofit 2.0 使用-补充篇
- Android Retrofit 2.5.0使用基础详解
在 Android 中使用 Retrofit 的简单 GET 请求(android retrofit原理)
网络是移动开发的关键因素。大多数(如果不是所有)移动应用程序都在某种程度上包含网络。应用程序正在发送或接收信息。最初,开发人员在主线程中处理网络
. 这使得应用程序的用户友好性降低,因为屏幕会“冻结”。
在 Honeycomb 版本发布后,主线程上的网络停止了。谷歌随后在 2013 年开发了 Volley。
介绍
你可以在这里阅读我关于 Volley 的文章。
Volley 提供了更好的东西:它更快、提供更好的功能、更简单的语法等。不过,在网络方面仍有增长空间。
Square 推出了 Retrofit。
Retrofit是一个类型安全的 HTTP 网络库,用于 Android 和 Java。Retrofit 更好,因为它超级快,提供更好的功能,甚至更简单的语法。从那时起,大多数开发人员都转而使用 Retrofit 来发出 API 请求。
改造的用途
Retrofit 用于执行以下任务:
- 它管理接收、发送和创建 HTTP 请求和响应的过程。
- 如果存在与 Web 服务故障的连接,它会交替使用 IP 地址。
- 它缓存响应以避免发送重复请求。
- 改造池连接以减少延迟。
- Retrofit 在发送错误和使应用程序崩溃之前解决问题。
改造的优势
- 它非常快。
- 它支持与 Web 服务的直接通信。
- 它易于使用和理解。
- 它支持请求取消。
- 它支持发布请求和分段上传。
- 它支持同步和异步网络请求。
- 支持动态 URL。
- 支持转换器。
改造的缺点
- 它不支持图像加载。它需要其他库,例如
Glide
和Picasso。 - 它不支持设置优先级。
改造中使用的类
- 模型类 - 此类包含要从 JSON 文件中获取的对象。
- Retrofit 实例 - 这个 Java 类用于向 API 发送请求。
- 接口类 - 此 Java 类用于定义端点。
先决条件
- 已安装Android Studio。
- 读者应该对 Java 和 XML 有初级的了解。
- 读者应该具备发出网络请求、JSON 和 REST API 的基本知识。
第 1 步 - 创建一个新的 Android 工作室项目
打开 Android Studio 并启动一个新的 Android Studio Project -> Empty Activity。选择完成并等待项目构建。
第 2 步 – 为我们的应用程序添加改造
将以下依赖项添加到您的应用级build.gradle
文件。
implementation 'com.squareup.retrofit2:retrofit:2.7.2'
implementation 'com.squareup.retrofit2:converter-gson:2.7.2'
implementation 'com.squareup.okhttp3:okhttp:3.6.0'
注意:可以根据想要使用的 JSON 添加不同的转换器。以下是一些转换器的示例:
Jackson : com.squareup.retrofit2:converter-jackson:2.1.0
moshi : com.squareup.retrofit2:converter-moshi:2.1.0
Protobuf : com.squareup.retrofit2:converter-protobuf:2.1.0
Wire : com.squareup.retrofit2:converter-wire:2.1.0
Simple XML : com.squareup.retrofit2:converter-simplexml:2.1.0
为您的应用程序添加互联网权限。
<uses-permission android:name="android.permission.INTERNET" />
第 3 步 – 为我们的应用程序设计 UI
在这一步中,我们将为我们的应用程序设计布局。由于这是一个简单的应用程序,我们将只使用 aListView
来显示 API 的信息。
将以下代码行添加到布局资源activity_main.xml文件中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".MainActivity">
<ListView
android:id="@+id/superListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
第 4 步 - 创建模型类
接下来,我们将创建一个包含来自 JSON 的对象的模型类。对于我们的例子,我们只想获取虚构人物的名字。
在Java目录下,右键选择new-→java class-→app/src/main/java-->class。我们将命名我们的模型类Results。
在 中添加以下代码行Results.java
:
package com.example.myapplication;
import com.google.gson.annotations.Serializedname;
public class Results {
@Serializedname("name")
private String superName;
public Results(String name) {
this.superName = name;
}
public String getName() {
return superName;
}
}
注意:Serializedname
注释应始终显示 JSON 文件中对象的确切名称。
第 5 步 - 创建改造实例
该 Java 类用于向 API 发送请求。我们指定包含所需数据的 URL 并使用Retrofit Builder
该类。
在Java目录下,右键选择new-→java class-→app/src/main/java-→class。我们将把我们的类命名为RetrofitClient。
将以下代码行添加到RetrofitClient.java
:
package com.example.myapplication;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
private static RetrofitClient instance = null;
private Api myApi;
private RetrofitClient() {
Retrofit retrofit = new Retrofit.Builder().baseUrl(Api.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
myApi = retrofit.create(Api.class);
}
public static synchronized RetrofitClient getInstance() {
if (instance == null) {
instance = new RetrofitClient();
}
return instance;
}
public Api getMyApi() {
return myApi;
}
}
第 6 步 – 定义端点
端点通常在接口类中定义。端点是指获取信息的路径。我们的终点是“奇迹”。由于我们的目标是从 API 获取信息,因此我们将使用@GET
注解,因为我们正在发出 Get 请求。
接下来,我们将拥有一个call<results>
从 API 返回信息的对象。
在Java目录下,右键选择new-->java class-->app/src/main/java-->class。我们将命名我们的接口类Api。
在 中添加以下代码行Api.java
:
package com.example.myapplication;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
public interface Api {
String BASE_URL = "https://simplifiedcoding.net/demos/";
@GET("marvel")
Call<List<Results>> getsuperHeroes();
}
@H_301_218@第 7 步 – 发送 GET 请求
在这一步中,我们将调用接口类中定义的每个 API 端点。接口类将使来自 API 的信息能够显示在我们的ListView
.
最后,我们将有一个onFailure
方法,Toast
如果信息没有成功加载到ListView
.
将以下代码行添加到您的 MainActivity.java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
ListView superListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
superListView = findViewById(R.id.superListView);
getSuperHeroes();
}
private void getSuperHeroes() {
Call<List<Results>> call = RetrofitClient.getInstance().getMyApi().getsuperHeroes();
call.enqueue(new Callback<List<Results>>() {
@Override
public void onResponse(Call<List<Results>> call, Response<List<Results>> response) {
List<Results> myheroList = response.body();
String[] oneHeroes = new String[myheroList.size()];
for (int i = 0; i < myheroList.size(); i++) {
oneHeroes[i] = myheroList.get(i).getName();
}
superListView.setAdapter(new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, oneHeroes));
}
@Override
public void onFailure(Call<List<Results>> call, Throwable t) {
Toast.makeText(getApplicationContext(), "An error has occured", Toast.LENGTH_LONG).show();
}
});
}
}
这就对了!
让我们运行我们的应用程序。
总结
我们了解到,网络是移动应用程序开发的关键因素。我们已经学习了如何使用 Retrofit 及其优缺点。
Android OkHttp + Retrofit 取消请求的方法
Android 2020
本文链接
前言
在某一个界面,用户发起了一个网络请求,因为某种原因用户在网络请求完成前离开了当前界面,比较好的做法是取消这个网络请求。对于OkHttp来说,具体是调用Call
的cancel
方法。
如何找到这一个网络请求并取消掉它呢?
操作大致分为3步。第一步,在建立请求时,给请求(request)添加标记;第二步,根据标记,找到请求;最后,取消这个请求。
OkHttp中的tag
要取消一个请求,OkHttp中可以使用cancel方法,参考。
OkHttp的request对象有tag。可以根据tag来标示请求。参考Stack Overflow。
//Set tags for your requests when you build them:
Request request = new Request.Builder().
url(url).tag("requestKey").build();
//When you want to cancel:
//A) go through the queued calls and cancel if the tag matches:
for (Call call : mHttpClient.dispatcher().queuedCalls()) {
if (call.request().tag().equals("requestKey"))
call.cancel();
}
//B) go through the running calls and cancel if the tag matches:
for (Call call : mHttpClient.dispatcher().runningCalls()) {
if (call.request().tag().equals("requestKey"))
call.cancel();
}
Retrofit中并没有显示地提供取消请求的接口。2018年时Retrofit仍未提供直接访问call对象的方法
那么如何找到目标网络请求呢?
Retrofit加入自定义header
给每个与页面(Activity,Fragment)相关的request加入自定义header,参考。
给OkHttpClient添加拦截器。标记出页面的生存状态。如果页面销毁了,则取消对应的request。
以GithubOnAndroid项目为例,https://github.com/RustFisher/GithubOnAndroid
添加标记
持有一个ConcurrentHashMap<String,Boolean>来标记页面存活状态。
private static ConcurrentHashMap<String,Boolean> actLiveMap = new ConcurrentHashMap<>(); // 标记Activity是否存活
public static void markPageAlive(String actName) {
actLiveMap.put(actName,true);
}
public static void markPageDestroy(String actName) {
actLiveMap.put(actName,false);
}
Activity中登记界面状态
给当前Activity起名字。每个Activity的标记名必须唯一。
private static final String MY_ACT_NAME = "xxx1Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NetworkCenter.markPageAlive(MY_ACT_NAME);
// ...
}
@Override
protected void onDestroy() {
super.onDestroy();
NetworkCenter.markPageDestroy(MY_ACT_NAME);
// ...
}
OkHttpClient添加拦截器
给OkHttpClient添加拦截器,在拦截器中检查页面的存活情况。
检查后,把这个自定义header移除掉。
public static final String HEADER_ACT_NAME = "Activity-Name"; // 标记Activity界面名字
private Interceptor lifeInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String actName = request.header(HEADER_ACT_NAME);
if (!TextUtils.isEmpty(actName)) {
Log.d(TAG,"lifeInterceptor: actName: " + actName);
Boolean actLive = actLiveMap.get(actName);
if (actLive == null || !actLive) {
chain.call().cancel();
Log.d(TAG,"lifeInterceptor: 取消请求,actName: " + actName);
} else {
Log.d(TAG,"lifeInterceptor: 发起请求,actName: " + actName);
}
}
Request newRequest = request.newBuilder().removeHeader(HEADER_ACT_NAME).build();
return chain.proceed(newRequest);
}
};
OkHttpClient = new OkHttpClient.Builder()
.readTimeout(10,TimeUnit.SECONDS)
.connectTimeout(10,TimeUnit.SECONDS)
.addInterceptor(lifeInterceptor) // 添加拦截器
.build();
call.cancel()后,不会再走Retrofit的subscribe方法。
添加header
@GET("users/{owner}/repos")
Observable<List<UserRepo>> userRepo(
@Header(NetworkCenter.HEADER_ACT_NAME) @Nullable String actName,@Path("owner") String owner,@Query("sort") String sortType);
android okhttp + retrofit使用
首先需要引入依赖
implementation 'com.squareup.okhttp3:okhttp:4.8.0' implementation 'com.squareup.okio:okio:2.7.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.google.code.gson:gson:2.8.6'
首先我们创建一个okhttpmanager单例类,为了获取okhttpclient
val builder = OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .sslSocketFactory( SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getTrustManager()[0] as x509trustmanager ) .hostnameVerifier(SSLSocketClient.getHostnameVerifier()) //cookieJar 处理okhttp和webview cookie同步 //.cookieJar(WebViewCookieHandler(context)) .cache(Cache(File(context.externalCacheDir, "okHttpCache"), Globals.REQUEST_CACHE_SIZE)) //拦截器,处理访问时携带的参数 builder.addInterceptor { val httpUrl = it.request().url val httpMainUrl = context.getString(R.string.url).toHttpUrlOrNull() val request: Request = if (httpUrl.host == httpMainUrl!!.host) { it.request().newBuilder() .addHeader("authenticate", MyApp.instance.userInfo().token ?: "") .build() } else { it.request() } it.proceed(request) } //拦截器 退出拦截 builder.addInterceptor { val request = it.request() val response = it.proceed(request) //这里约定后台返回401状态码,就表示没有登录状态了 if (response.code == 401) { //这里需要进行退出系统处理 return@addInterceptor response.newBuilder().build() } return@addInterceptor response } //这样就获取到okhttpclient了 builder.build()
这里贴上上面用到的 SSLSocketClient类
public class SSLSocketClient { private static final List<String> VERIFY_HOST_NAME_ARRAY = new ArrayList<String>(){{ add("www.test.com"); }}; //获取这个SSLSocketFactory public static SSLSocketFactory getSSLSocketFactory() { try { //SSLContext sslContext = SSLContext.getInstance("SSL"); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, getTrustManager(), new SecureRandom()); return sslContext.getSocketFactory(); } catch (Exception e) { throw new RuntimeException(e); } } //获取TrustManager public static TrustManager[] getTrustManager() { return new TrustManager[]{ new x509trustmanager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { } @Override public X509Certificate[] getAcceptedissuers() { return new X509Certificate[]{}; } } }; } //获取HostnameVerifier public static HostnameVerifier getHostnameVerifier() { return (s, sslSession) -> { if(TextUtils.isEmpty(s)){ return false; } return !Arrays.asList(VERIFY_HOST_NAME_ARRAY).contains(s); }; } }
然后我们开始写retrofitclient类
class RetrofitClient private constructor() { private lateinit var retrofit: Retrofit companion object { val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { RetrofitClient() } } init { createRetrofit() } private fun createRetrofit() { retrofit = Retrofit.Builder().baseUrl("https://www.test.com/web-api/") .client(OkHttpManager.instance.client()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build() } fun <T> getService(service: Class<T>): T { return retrofit.create(service) } }
然后定义api
interface LoginApi { @PUT("login") fun login(@Query("username") username :String,@Query("pass") pass :String):Observable<ResponseWrapper<LoginRespBean>> }
@GET get请求 @POST post请求 @PUT put 请求 @DELETE delete请求
一般put请求我们一般会使用@Body传递 比如 @Body loginBean:LoginBean LoginBean(username,pass)
@Path [@GET("user/{id}") fun userInfo(@Path("id") uid:String) ]
LoginRespBean 定义的用户的唯一ID ,用户的一些基本信息和登录凭证信息
接下来我们开始使用
RetrofitClient.instance.getService(LoginApi::class.java) .login("用户名", "密码") .compose(NetworkScheduler.compose()) .subscribe({ if (it.code == RespCode.OK) { //登录成功 } else { //登录失败 } }, { //出现异常了 //这里异常的代码块,我们不能省略,可以空实现,如果配置了全局异常处理,异常处理的代码块可以省略掉
//subscribe {}
}) //这里贴一下全局异常处理 这个代码放到自定义的application类中即可 RxJavaPlugins.setErrorHandler { MyLog.e("RxJava统一错误处理", "======" + it.message) }
NetworkScheduler类
object NetworkScheduler { fun <T> compose(): ObservableTransformer<T,T>{ return ObservableTransformer { it.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) } } }
Android Retrofit 2.0 使用-补充篇
推荐阅读,猛戳:
1、Android MVP 实例
2、Android Retrofit 2.0使用
3、RxJava
4、RxBus
5、Android MVP+Retrofit+RxJava实践小结
之前分享的Android Retrofit 2.0 使用,属于基本的使用,实际开发还远远不够,因此对其补充,主要在Retrofit配置和接口参数。
Retrofit配置
添加依赖
app/build.gradle
compile ''com.squareup.retrofit2:retrofit:2.0.2''
首先Builder(),得到OkHttpClient.Builder对象builder
OkHttpClient.Builder builder = new OkHttpClient.Builder();
Log信息拦截器
Debug可以看到,网络请求,打印Log信息,发布的时候就不需要这些log
1、添加依赖
app/build.gradle
compile ''com.squareup.okhttp3:logging-interceptor:3.1.2''
2、Log信息拦截器
if (BuildConfig.DEBUG) {
// Log信息拦截器
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//设置 Debug Log 模式
builder.addInterceptor(loggingInterceptor);
}
缓存机制
无网络时,也能显示数据
File cacheFile = new File(DemoApplication.getContext().getExternalCacheDir(), "WuXiaolongCache");
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
Interceptor cacheInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!AppUtils.networkIsAvailable(DemoApplication.getContext())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (AppUtils.networkIsAvailable(DemoApplication.getContext())) {
int maxAge = 0;
// 有网络时 设置缓存超时时间0个小时
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.removeHeader("WuXiaolong")// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
.build();
} else {
// 无网络时,设置超时为4周
int maxStale = 60 * 60 * 24 * 28;
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.removeHeader("nyn")
.build();
}
return response;
}
};
builder.cache(cache).addInterceptor(cacheInterceptor);
公共参数
可能接口有某些参数是公共的,不可能一个个接口都去加吧
//公共参数
Interceptor addQueryParameterInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request request;
String method = originalRequest.method();
Headers headers = originalRequest.headers();
HttpUrl modifiedUrl = originalRequest.url().newBuilder()
// Provide your custom parameter here
.addQueryParameter("platform", "android")
.addQueryParameter("version", "1.0.0")
.build();
request = originalRequest.newBuilder().url(modifiedUrl).build();
return chain.proceed(request);
}
};
//公共参数
builder.addInterceptor(addQueryParameterInterceptor);
设置头
有的接口可能对请求头要设置
Interceptor headerInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder requestBuilder = originalRequest.newBuilder()
.header("AppType", "TPOS")
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.method(originalRequest.method(), originalRequest.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
};
//设置头
builder.addInterceptor(headerInterceptor );
设置cookie
服务端可能需要保持请求是同一个cookie,主要看各自需求
1、app/build.gradle
compile ''com.squareup.okhttp3:okhttp-urlconnection:3.2.0''
2、设置cookie
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
builder.cookieJar(new JavaNetCookieJar(cookieManager));
设置超时和重连
希望超时时能重连
//设置超时
builder.connectTimeout(15, TimeUnit.SECONDS);
builder.readTimeout(20, TimeUnit.SECONDS);
builder.writeTimeout(20, TimeUnit.SECONDS);
//错误重连
builder.retryOnConnectionFailure(true);
最后将这些配置设置给retrofit:
OkHttpClient okHttpClient = builder.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiStores.API_SERVER_URL)
//设置 Json 转换器
.addConverterFactory(GsonConverterFactory.create())
//RxJava 适配器
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
完整配置
public class AppClient {
public static Retrofit retrofit = null;
public static Retrofit retrofit() {
if (retrofit == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
/**
*设置缓存,代码略
*/
/**
* 公共参数,代码略
*/
/**
* 设置头,代码略
*/
/**
* Log信息拦截器,代码略
*/
/**
* 设置cookie,代码略
*/
/**
* 设置超时和重连,代码略
*/
//以上设置结束,才能build(),不然设置白搭
OkHttpClient okHttpClient = builder.build();
retrofit = new Retrofit.Builder()
.baseUrl(ApiStores.API_SERVER_URL)
.client(okHttpClient)
.build();
}
return retrofit;
}
}
接口参数
Path
类似这样链接:http://wuxiaolong.me/2016/01/...
@GET("2016/01/15/{retrofit}")
Call<ResponseBody> getData(@Path("retrofit") String retrofit);
即您传的参数retrofit内容会替换大括号里的内容。
Query
类似这样链接:http://wuxiaolong.me/v1?ip=20...
@GET("v1")
Call<ResponseBody> getData(@Query("ip") String ip,@Query("name") String name);
Field
表单提交,如登录
@FormUrlEncoded
@POST("v1/login")
Call<ResponseBody> userLogin(@Field("phone") String phone, @Field("password") String password);
传json格式
如果参数是json格式,如:
{
"apiInfo": {
"apiName": "WuXiaolong",
"apiKey": "666"
}
}
建立Bean
public class ApiInfo {
private ApiInfoBean apiInfo;
public ApiInfoBean getApiInfo() {
return apiInfo;
}
public void setApiInfo(ApiInfoBean apiInfo) {
this.apiInfo = apiInfo;
}
public class ApiInfoBean {
private String apiName;
private String apiKey;
//省略get和set方法
}
}
ApiStores
@POST("client/shipper/getCarType")
Call<ResponseBody> getData(@Body ApiInfo apiInfo);
代码调用
ApiInfo apiInfo = new ApiInfo();
ApiInfo.ApiInfoBean apiInfoBean = apiInfo.new ApiInfoBean();
apiInfoBean.setApiKey("666");
apiInfoBean.setApiName("WuXiaolong");
apiInfo.setApiInfo(apiInfoBean);
//调接口
getData(apiInfo);
传数组
@GET("v1/enterprise/find")
Call<ResponseBody> getData(@Query("id") String id, @Query("linked[]") String... linked);
代码调用
String id="WuXiaolong";
String[] s = new String[]{"WuXiaolong"};
//调接口
getData(id, s);
传文件-单个
@Multipart
@POST("v1/create")
Call<ResponseBody> create(@Part("pictureName") RequestBody pictureName, @Part MultipartBody.Part picture);
代码调用
RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");
File picture= new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part picturePart = MultipartBody.Part.createFormData("picture", picture.getName(), requestFile);
//调接口
create(pictureNameBody, picturePart);
传文件-多个
@Multipart
@POST("v1/create")
Call<ResponseBody> create(@Part("pictureName") RequestBody pictureName, @PartMap Map<String, RequestBody> params);
代码调用
RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");
File picture= new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);
Map<String, RequestBody> params = new HashMap<>();
params.put("picture\"; filename=\"" + picture.getName() + "", requestFile);
//调接口
create(pictureNameBody, params);
微信公众号
我的微信公众号:吴小龙同学。
Android Retrofit 2.5.0使用基础详解
前言
- 在Andrroid开发中,网络请求必不可少
- 而在Android所有网络请求库中,
Retrofit
是最受开发者欢迎的一个网络请求库
retrofit:2.5.0 官方文档
retrofit:2.5.0 - github
简介
-
Retrofit
是Square公司开发的一款针对Android网络请求的框架,遵循Restful设计风格,底层基于OkHttp.
功能
- 支持同步/异步网络请求
- 支持多种数据的解析&序列化格式(Gson、json、XML等等)
- 通过注解配置网络请求参数
- 提供对Rxjava的支持
- 高度解耦,使用方便
对比其他网络请求框架
- 性能最好,速度最快
- 高度封装导致扩展性差
- 简洁易用,代码简化
- 解耦彻底,职责细分
- 易与其他框架联用(Rxjava)
使用场景
- 任何场景下建议优先使用
网络请求流程
- App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作
- 在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析
具体使用
1.添加Retrofit库的依赖
dependencies {
implementation ''com.squareup.retrofit2:retrofit:2.5.0''
api ''com.squareup.retrofit2:converter-gson:2.0.2''
}
2. 添加 网络权限
<uses-permission android:name="android.permission.INTERNET"/>
3. 创建 装载服务器返回数据 的类
public class ResultData{
...
// 根据返回数据的格式和数据解析方式(Json、XML等)定义
}
4. 创建 用于配置网络请求 的接口
- Retrofit将 Http请求 抽象成 Java接口:采用 注解 描述网络请求参数 和配置网络请求参数
public interface GetRequestInterface {
@GET("openapi.do?keyfrom=Yanzhikai&key=2032414398&type=data&doctype=json&version=1.1&q=car")
Call<ResultData> getCall();
// @GET注解的作用:采用Get方法发送网络请求
// getCall() = 接收网络请求数据的方法
// 其中返回类型为Call<*>,*是接收数据的类(即上面定义的Translation类)
// 如果想直接获得Responsebody中的内容,可以定义网络请求返回值为Call<ResponseBody>
}
注解说明
- 网络请求方法:@GET、@POST、@PUT、@DELETE、@HEAD(常用)
- 网络请求标记: @FormUrlEncoded、@Multipart、@Streaming
- 网络请求参数: @Header &、@Headers、 @Body、@Field 、 @FieldMap、@Part 、 @PartMap、@Query、@QueryMap、@Path、@Url
具体作用以及解释请自行前往官方文档查看,这里就不一一解释了
5. 创建 Retrofit 实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://fanyi.youdao.com/") // 设置网络请求的公共Url地址
.addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 支持RxJava平台
.build();
- 数据解析器说明
Retrofit支持多种数据解析方式,使用时需要在Gradle添加依赖
数据解析器
Gradle依赖
Gson
com.squareup.retrofit2:converter-gson:2.0.2
Jackson
com.squareup.retrofit2:converter-jackson:2.0.2
Simple XML
com.squareup.retrofit2:converter-simplexml:2.0.2
Protobuf
com.squareup.retrofit2:converter-protobuf:2.0.2
Moshi
com.squareup.retrofit2:converter-moshi:2.0.2
Wire
com.squareup.retrofit2:converter-wire:2.0.2
Scalars
com.squareup.retrofit2:converter-scalars:2.0.2
- 网络适配器说明
Retrofit支持多种网络请求适配器方式:guava、Java8和rxjava
Android 提供默认的 CallAdapter,不需要添加网络请求适配器的依赖,若要使用其他网络适配器,则需要按照需求在Gradle添加依赖
网络请求适配器
Gradle依赖
guava
com.squareup.retrofit2:adapter-guava:2.0.2
Java8
com.squareup.retrofit2:adapter-java8:2.0.2
rxjava
com.squareup.retrofit2:adapter-rxjava:2.0.2
6.创建 网络请求接口实例
// 创建 网络请求接口 的实例
GetRequestInterface request = retrofit.create(GetRequestInterface.class);
//对 发送请求 进行封装
Call<ResultData> call = request.getCall();
7. 发起网络请求(异步 / 同步)
/发送网络请求(异步)
call.enqueue(new Callback<ResultData>() {
//请求成功时回调
@Override
public void onResponse(Call<ResultData> call, Response<ResultData> response) {
//处理结果
}
//请求失败时候的回调
@Override
public void onFailure(Call<ResultData> call, Throwable throwable) {
//提示失败
}
});
// 发送网络请求(同步)
Response<ResultData> response = call.execute();
8. 处理返回数据
//发送网络请求(异步)
call.enqueue(new Callback<ResultData>() {
//请求成功时回调
@Override
public void onResponse(Call<ResultData> call, Response<ResultData> response) {
// 对返回数据进行处理
response.body();//拿到ResultData对象进行数据操作
}
//请求失败时候的回调
@Override
public void onFailure(Call<ResultData> call, Throwable throwable) {
System.out.println("连接失败");
}
});
// 发送网络请求(同步)
Response<ResultData> response = call.execute();
// 对返回数据进行处理
response.body().blabla;
总结
- Retrofit 是一个 restful 的 HTTP 网络请求框架的封装。
- 网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装
- App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作
- 在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析
- 相对其他开源库而言代码简洁使用更加方便.
关于Retrofit 2.5的简单介绍到这里就结束了,感谢阅读.
参考文章:
- Android Retrofit 2.0 的详细 使用攻略(含实例讲解)
- Android:手把手带你 深入读懂 Retrofit 2.0 源码
欢迎关注作者darryrzhong,更多干货等你来拿哟.
请赏个小红心!因为你的鼓励是我写作的最大动力!
更多精彩文章请关注
- 个人博客:darryrzhong
- 掘金
- 简书
- SegmentFault
- 慕课网手记
关于在 Android 中使用 Retrofit 的简单 GET 请求和android retrofit原理的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Android OkHttp + Retrofit 取消请求的方法、android okhttp + retrofit使用、Android Retrofit 2.0 使用-补充篇、Android Retrofit 2.5.0使用基础详解的相关信息,请在本站寻找。
本文标签: