GVKun编程网logo

在 Android 中使用 Retrofit 的简单 GET 请求(android retrofit原理)

22

在本文中,我们将给您介绍关于在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 中使用 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 OkHttp + Retrofit 取消请求的方法

Android 2020

本文链接

前言

在某一个界面,用户发起了一个网络请求,因为某种原因用户在网络请求完成前离开了当前界面,比较好的做法是取消这个网络请求。对于OkHttp来说,具体是调用Callcancel方法。

如何找到这一个网络请求并取消掉它呢?

操作大致分为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使用

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 使用-补充篇

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使用基础详解

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使用基础详解的相关信息,请在本站寻找。

本文标签: