Android 示例教程的改装步骤范例

欢迎来到Retrofit Android示例教程。今天我们将使用由Square开发的Retrofit库,在我们的Android应用程序中处理REST API调用。

改造安卓系统

Retrofit 是一种适用于 Android 和 Java 的类型安全的 REST 客户端,旨在更轻松地使用 RESTful web 服务。我们不会详细介绍 Retrofit 1.x 版本,直接跳转到 Retrofit 2,它拥有许多新功能并且与以前的版本相比具有改变的内部 API。默认情况下,Retrofit 2 使用 OkHttp 作为网络层,并在其之上构建。Retrofit 会自动序列化 JSON 响应,使用一个 POJO(Plain Old Java Object)来定义 JSON 结构必须提前定义。为了序列化 JSON,我们需要一个转换器将其首先转换为 Gson。我们需要在 build.gradle 文件中添加以下依赖项。

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

Retrofit 2已经包含了OkHttp依赖项。如果你想使用单独的OkHttp依赖项,你应该从Retrofit 2中排除OkHttp依赖项。

compile ('com.squareup.retrofit2:retrofit:2.1.0') {  
  // exclude Retrofit’s OkHttp dependency module and define your own module import
  exclude module: 'okhttp'
}
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
compile 'com.squareup.okhttp3:okhttps:3.4.1'
  • The logging-interceptor generates a log string of the entire response that’s returned.
  • There are other converters to parse the JSON to the necessary type. A few of them are listed below.
    1. Jackson: com.squareup.retrofit2:converter-jackson:2.1.0

 

    1. Moshi: com.squareup.retrofit2:converter-moshi:2.1.0

 

    1. Protobuf: com.squareup.retrofit2:converter-protobuf:2.1.0

 

    1. Wire: com.squareup.retrofit2:converter-wire:2.1.0

 

    1. Simple XML: com.squareup.retrofit2:converter-simplexml:2.1.0

杰克逊:com.squareup.retrofit2:converter-jackson:2.1.0
莫仕:com.squareup.retrofit2:converter-moshi:2.1.0
协议缓冲:com.squareup.retrofit2:converter-protobuf:2.1.0
Wire:com.squareup.retrofit2:converter-wire:2.1.0
简单XML:com.squareup.retrofit2:converter-simplexml:2.1.0

在AndroidManifest.xml文件中添加访问互联网的权限。

OkHttp 拦截器

拦截器是OkHttp中的一个强大机制,可以监视、重写和重试调用。拦截器主要分为两类:

  • Application Interceptors : To register an application interceptor, we need to call addInterceptor() on OkHttpClient.Builder
  • Network Interceptors : To register a Network Interceptor, invoke addNetworkInterceptor() instead of addInterceptor()

建立Retrofit接口

package com.Olivia.retrofitintro;

import com.Olivia.retrofitintro.pojo.MultipleResource;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

class APIClient {

    private static Retrofit retrofit = null;

    static Retrofit getClient() {

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();


        retrofit = new Retrofit.Builder()
                .baseUrl("https://reqres.in")
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();



        return retrofit;
    }

}

以上代码中的getClient()方法将在设置Retrofit接口时每次被调用。Retrofit为每个HTTP方法提供了一组注解,包括@GET、@POST、@PUT、@DELETE、@PATCH或@HEAD。现在让我们看看我们的APIInterface.java类是什么样的。

package com.Olivia.retrofitintro;

import com.Olivia.retrofitintro.pojo.MultipleResource;
import com.Olivia.retrofitintro.pojo.User;
import com.Olivia.retrofitintro.pojo.UserList;

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;

interface APIInterface {

    @GET("/api/unknown")
    Call<MultipleResource> doGetListResources();

    @POST("/api/users")
    Call<User> createUser(@Body User user);

    @GET("/api/users?")
    Call<UserList> doGetUserList(@Query("page") String page);

    @FormUrlEncoded
    @POST("/api/users?")
    Call<UserList> doCreateUserWithField(@Field("name") String name, @Field("job") String job);
}

在以上课堂上,我们定义了一些使用注解执行HTTP请求的方法。@GET(“/api/unknown”)调用doGetListResources()方法。doGetListResources()是方法名称。MultipleResource.java是我们用来将响应参数映射到相应变量的响应对象的模型POJO类。这些POJO类充当方法的返回类型。以下是一个简单的MultipleResources.java的POJO类。

package com.Olivia.retrofitintro.pojo;

import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;
import java.util.List;

public class MultipleResource {

    @SerializedName("page")
    public Integer page;
    @SerializedName("per_page")
    public Integer perPage;
    @SerializedName("total")
    public Integer total;
    @SerializedName("total_pages")
    public Integer totalPages;
    @SerializedName("data")
    public List<Datum> data = null;

    public class Datum {

        @SerializedName("id")
        public Integer id;
        @SerializedName("name")
        public String name;
        @SerializedName("year")
        public Integer year;
        @SerializedName("pantone_value")
        public String pantoneValue;

    }
}

@SerializedName注解用于指定JSON响应中的字段名称。预览POJO类并将其复制到您的Android Studio项目结构中。POJO类被包装到一个带类型的Retrofit Call类中。注意:JSONArray被序列化为POJO类的对象列表。方法参数:方法内部可以传递各种可能的参数选项。

  • @Body – Sends Java objects as request body.
  • @Url – use dynamic URLs.
  • @Query – We can simply add a method parameter with @Query and a query parameter name, describing the type. To URL encode a query use the form: @Query(value = “auth_token”,encoded = true) String auth_token
  • @Field – send data as form-urlencoded. This requires a @FormUrlEncoded annotation attached with the method. The @Field parameter works only with a POST

注意:@Field需要一个强制参数。在@Field为可选的情况下,我们可以使用@Query并传递一个null值。

Android示例项目结构的改造

POJO包在APIInterface.java类中为每个API端点响应定义了四个模型类,其中包括User.java。

package com.Olivia.retrofitintro.pojo;

import com.google.gson.annotations.SerializedName;

public class User {

    @SerializedName("name")
    public String name;
    @SerializedName("job")
    public String job;
    @SerializedName("id")
    public String id;
    @SerializedName("createdAt")
    public String createdAt;

    public User(String name, String job) {
        this.name = name;
        this.job = job;
    }


}

上述类用于在UserList.java文件中为createUser()方法创建响应体。

package com.Olivia.retrofitintro.pojo;

import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;
import java.util.List;

public class UserList {

    @SerializedName("page")
    public Integer page;
    @SerializedName("per_page")
    public Integer perPage;
    @SerializedName("total")
    public Integer total;
    @SerializedName("total_pages")
    public Integer totalPages;
    @SerializedName("data")
    public List<Datum> data = new ArrayList();

    public class Datum {

        @SerializedName("id")
        public Integer id;
        @SerializedName("first_name")
        public String first_name;
        @SerializedName("last_name")
        public String last_name;
        @SerializedName("avatar")
        public String avatar;

    }
}

创建用户响应.java

package com.Olivia.retrofitintro.pojo;

import com.google.gson.annotations.SerializedName;

public class CreateUserResponse {

    @SerializedName("name")
    public String name;
    @SerializedName("job")
    public String job;
    @SerializedName("id")
    public String id;
    @SerializedName("createdAt")
    public String createdAt;
}

MainActivity.java是我们调用在Interface类中定义的每个API端点并在Toast/TextView中显示每个字段的地方。

package com.Olivia.retrofitintro;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.Olivia.retrofitintro.pojo.CreateUserResponse;
import com.Olivia.retrofitintro.pojo.MultipleResource;
import com.Olivia.retrofitintro.pojo.User;
import com.Olivia.retrofitintro.pojo.UserList;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    TextView responseText;
    APIInterface apiInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        responseText = (TextView) findViewById(R.id.responseText);
        apiInterface = APIClient.getClient().create(APIInterface.class);


        /**
         GET List Resources
         **/
        Call<MultipleResource> call = apiInterface.doGetListResources();
        call.enqueue(new Callback<MultipleResource>() {
            @Override
            public void onResponse(Call<MultipleResource> call, Response<MultipleResource> response) {


                Log.d("TAG",response.code()+"");

                String displayResponse = "";

                MultipleResource resource = response.body();
                Integer text = resource.page;
                Integer total = resource.total;
                Integer totalPages = resource.totalPages;
                List<MultipleResource.Datum> datumList = resource.data;

                displayResponse += text + " Page\n" + total + " Total\n" + totalPages + " Total Pages\n";

                for (MultipleResource.Datum datum : datumList) {
                    displayResponse += datum.id + " " + datum.name + " " + datum.pantoneValue + " " + datum.year + "\n";
                }

                responseText.setText(displayResponse);

            }

            @Override
            public void onFailure(Call<MultipleResource> call, Throwable t) {
                call.cancel();
            }
        });

        /**
         Create new user
         **/
        User user = new User("morpheus", "leader");
        Call<User> call1 = apiInterface.createUser(user);
        call1.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                User user1 = response.body();

                Toast.makeText(getApplicationContext(), user1.name + " " + user1.job + " " + user1.id + " " + user1.createdAt, Toast.LENGTH_SHORT).show();

            }

            @Override
            public void onFailure(Call<User> call, Throwable t) {
                call.cancel();
            }
        });

        /**
         GET List Users
         **/
        Call<UserList> call2 = apiInterface.doGetUserList("2");
        call2.enqueue(new Callback<UserList>() {
            @Override
            public void onResponse(Call<UserList> call, Response<UserList> response) {

                UserList userList = response.body();
                Integer text = userList.page;
                Integer total = userList.total;
                Integer totalPages = userList.totalPages;
                List<UserList.Datum> datumList = userList.data;
                Toast.makeText(getApplicationContext(), text + " page\n" + total + " total\n" + totalPages + " totalPages\n", Toast.LENGTH_SHORT).show();

                for (UserList.Datum datum : datumList) {
                    Toast.makeText(getApplicationContext(), "id : " + datum.id + " name: " + datum.first_name + " " + datum.last_name + " avatar: " + datum.avatar, Toast.LENGTH_SHORT).show();
                }


            }

            @Override
            public void onFailure(Call<UserList> call, Throwable t) {
                call.cancel();
            }
        });


        /**
         POST name and job Url encoded.
         **/
        Call<UserList> call3 = apiInterface.doCreateUserWithField("morpheus","leader");
        call3.enqueue(new Callback<UserList>() {
            @Override
            public void onResponse(Call<UserList> call, Response<UserList> response) {
                UserList userList = response.body();
                Integer text = userList.page;
                Integer total = userList.total;
                Integer totalPages = userList.totalPages;
                List<UserList.Datum> datumList = userList.data;
                Toast.makeText(getApplicationContext(), text + " page\n" + total + " total\n" + totalPages + " totalPages\n", Toast.LENGTH_SHORT).show();

                for (UserList.Datum datum : datumList) {
                    Toast.makeText(getApplicationContext(), "id : " + datum.id + " name: " + datum.first_name + " " + datum.last_name + " avatar: " + datum.avatar, Toast.LENGTH_SHORT).show();
                }

            }

            @Override
            public void onFailure(Call<UserList> call, Throwable t) {
                call.cancel();
            }
        });

    }
}

使用“`apiInterface = APIClient.getClient().create(APIInterface.class);“`来实例化APIClient。为了将Model类映射到响应中,我们使用“`MultipleResource resource = response.body();“`。运行应用程序会调用每个端点并相应地显示Toast消息。这就结束了Retrofit Android示例教程。你可以从下面的链接下载Android Retrofit示例项目。

下载Retrofit Android示例项目

发表回复 0

Your email address will not be published. Required fields are marked *


广告
将在 10 秒后关闭
bannerAds