OkHttp,Retrofit 1.x - 2.x 基本使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OkHttp,Retrofit 1.x - 2.x 基本使用相关的知识,希望对你有一定的参考价值。

  Square 为广大开发者奉献了OkHttp,Retrofit1.x,Retrofit2.x,运用比较广泛,这三个工具有很多相似之处,初学者可能会有一些使用迷惑。这里来总结一下它们的一些基本使用和一些细微差别。

/**************
Retrofit 基本使用方法

Retrofit 到底是返回什么? void, Observable, Call?

*************/
/********************************************Retrofit****************************************************************/
/*** 同步调用的方式  ****/
interface GitHubService {
  @GET("/repos/{owner}/{repo}/contributors")
  List<Contributor> repoContributors(
      @Path("owner") String owner,
      @Path("repo") String repo);
} 

List<Contributor> contributors =
    gitHubService.repoContributors("square", "retrofit");
/***** 异步调用的方式 仅限于 Retrofit 1.x !!!!!!! *****/
interface GitHubService {
  @GET("/repos/{owner}/{repo}/contributors")
  void repoContributors(
      @Path("owner") String owner,
      @Path("repo") String repo,
      Callback<List<Contributor>> cb); // 异步调用添加 CallBack
} 

service.repoContributors("square", "retrofit", new Callback<List<Contributor>>() {
  @Override void success(List<Contributor> contributors, Response response) {
    // ...
  }


  @Override void failure(RetrofitError error) {
    // ...
  }
});

/**** Rxjava 方式 ****/
interface GitHubService {
  @GET("/repos/{owner}/{repo}/contributors")
  Observable<List<Contributor>> repoContributors(
      @Path("owner") String owner,
      @Path("repo") String repo);
} 
// 调用
gitHubService.repoContributors("square", "retrofit")
    .subscribe(new Action1<List<Contributor>>() {
      @Override public void call(List<Contributor> contributors) {
        // ...
      }
    });
    
/*******************************注意以下三个Callback的不同***************************************/
	
// Retrofit Callback Version 1.9 
public interface Callback<T> {

  /** Successful HTTP response. */
  void success(T t, Response response);

  /**
   * Unsuccessful HTTP response due to network failure, non-2XX status code, or unexpected
   * exception.
   */
  void failure(RetrofitError error);
}
// Retrofit Callback Version 2.0	!!!!!!!!!
public interface Callback<T> {
  /** Successful HTTP response. */
  void onResponse(Response<T> response, Retrofit retrofit);

  /** Invoked when a network or unexpected exception occurred during the HTTP request. */
  void onFailure(Throwable t);
}
// OkHttp	
public interface Callback {
  void onFailure(Request request, IOException e);

  void onResponse(Response response) throws IOException; // 注意参数不同
}



/*********************************回顾一下Okhttp的调用方式********************************************/

//1. 创建 
OkHttpClient : OkHttpClient client = new OkHttpClient();
//2. 创建 
Request :  Request request = new Request.Builder()
									    .url("https://api.github.com/repos/square/okhttp/issues")
										.header("User-Agent", "OkHttp Headers.java")
										.addHeader("Accept", "application/json; q=0.5")
										.addHeader("Accept", "application/vnd.github.v3+json")
										.build();
												
//3. 使用 client 执行请求(两种方式):  
//第一种,同步执行
Response response = client.newCall(request).execute();
// 第二种,异步执行方式
client.newCall(request).enqueue(new Callback() { 
    @Override 
    public void onFailure(Request request, Throwable throwable) {
    // 复写该方法
											 
    }
    @Override public void onResponse(Response response) throws IOException {
	// 复写该方法
    }									   
}
	
	
/***********************************Retrofit 1.0 不能获得 Header 或者整个 Body*****************************************/
/**********引入 Call , 每个Call只能调用一次,可以使用Clone方法来生成一次调用多次,使用Call既可以同步也可以异步*********/

interface GitHubService {
  @GET("/repos/{owner}/{repo}/contributors")
  Call<List<Contributor>> repoContributors(
      @Path("owner") String owner,
      @Path("repo") String repo);
}

Call<List<Contributor>> call =
    gitHubService.repoContributors("square", "retrofit");

response = call.execute(); /*************** 同步的方式调用,注意这里返回了 Response 后面会提到 ********************/

// This will throw IllegalStateException: 每个Call只能执行一次
response = call.execute();

Call<List<Contributor>> call2 = call.clone(); // 调用Clone之后又可以执行
// This will not throw:
response = call2.execute();

/************************ 异步的方式调用 *********************************/

Call<List<Contributor>> call =
    gitHubService.repoContributors("square", "retrofit");

call.enqueue(new Callback<List<Contributor>>() {
  @Override void onResponse(/* ... */) {
    // ...
  }

  @Override void onFailure(Throwable t) {
    // ...
  }
});

/****************************引入 Response,获取返回的RawData,包括:response code, response message, headers**********************************/

class Response<T> {
  int code();
  String message();
  Headers headers();

  boolean isSuccess(); 
  T body();
  ResponseBody errorBody(); 
  com.squareup.okhttp.Response raw();
}

interface GitHubService {
  @GET("/repos/{owner}/{repo}/contributors")
  Call<List<Contributor>> repoContributors(
      @Path("owner") String owner,
      @Path("repo") String repo);
} 

Call<List<Contributor>> call = 
    gitHubService.repoContributors("square", "retrofit");
Response<List<Contributor>> response = call.execute(); 

/*********************************** Dynamic URL *****************************************/

interface GitHubService {
  @GET("/repos/{owner}/{repo}/contributors")
  Call<List<Contributor>> repoContributors(
      @Path("owner") String owner,
      @Path("repo") String repo);

  @GET
  Call<List<Contributor>> repoContributorsPaginate(
      @Url String url);// 直接填入 URL 而不是在GET中替换字段的方式
}

/*************************************根据返回值实现重载*****************************************************/
interface SomeService {
  @GET("/some/proto/endpoint")
  Call<SomeProtoResponse> someProtoEndpoint(); // SomeProtoResponse

  @GET("/some/json/endpoint")
  Call<SomeJsonResponse> someJsonEndpoint(); // SomeJsonResponse
}

interface GitHubService {
  @GET("/repos/{owner}/{repo}/contributors")
  Call<List<Contributor>> repoContributors(..);

  @GET("/repos/{owner}/{repo}/contributors")
  Observable<List<Contributor>> repoContributors2(..);

  @GET("/repos/{owner}/{repo}/contributors")
  Future<List<Contributor>> repoContributors3(..); // 可以返回 Future
}

/******************************************Retrofit 1.x Interceptor,添加头部信息的时候经常用到Interceptor*************************************************************/
    RestAdapter.Builder builder = new RestAdapter.Builder().setRequestInterceptor(new RequestInterceptor() {
        @Override
        public void intercept(RequestFacade request) {
            request.addHeader("Accept", "application/json;versions=1");
        }
    });


/******************************************Retrofit 2.x Interceptor**************************************************/            
    
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {    
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = chain.request();
        
        Request request = original.newBuilder()
                                  .header("Accept", "application/json")
                                  .header("Authorization", "auth-token")
                                  .method(original.method(), original.body())
                                  .build();
       
       Response response = chain.proceed(request);
       return response;      
        
    }   
}

Retrofit retrofit = Retrofit.Builder()
            .baseUrl("https://your.api.url/v2/")
            .client(client).build();


/***************************************异步实例*********************************************/
public interface APIService {

    @GET("/users/{user}/repos")
    Call<List<Repo>> listRepos(@Path("user") String user);

    @GET("/users/{user}/repos")
    Call<String> listReposStr(@Path("user") String user);
//错误,不能这样使用异步
//    @GET("/users/{user}/repos")
//    void listRepos(@Path("user") String user, Callback<List<Repo>> callback);
}

private void prepareServiceAPI() {
    //For logging
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new MyInterceptor());
    client.interceptors().add(logging);
	// setUp Retrofit 
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://api.github.com")
            //.addConverterFactory(new ToStringConverterFactory())
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();

    service = retrofit.create(APIService.class);
}
// 异步调用
public void execute() {
    Call<List<Repo>> call = service.listRepos("pasha656");
    call.enqueue(new Callback<List<Repo>>() {
        @Override
        public void onResponse(Response<List<Repo>> response, Retrofit retrofit) {

            if (response.isSuccess()) {
                if (!response.body().isEmpty()) {
                    StringBuilder sb = new StringBuilder();
                    for (Repo r : response.body()) {
                        sb.append(r.getId()).append(" ").append(r.getName()).append(" \n");
                    }
                    activity.setText(sb.toString());
                }
            } else {
                APIError error = ErrorUtils.parseError(response, retrofit);
                Log.d("Pasha", "No succsess message "+error.getMessage());
            }


            if (response.errorBody() != null) {
                try {
                    Log.d("Pasha", "Error "+response.errorBody().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onFailure(Throwable t) {
            Log.d("Pasha", "onFailure "+t.getMessage());
        }
    });
}

  

以上是关于OkHttp,Retrofit 1.x - 2.x 基本使用的主要内容,如果未能解决你的问题,请参考以下文章

Retrofit 使用简介

带你走通 OkHttp+Retrofit+Rxjava

带你走通 OkHttp+Retrofit+Rxjava

Retrofit--使用Retrofit时怎样去设置OKHttp

Retrofit/OkHTTP/RxJava 间歇性 InterruptedIOException

Retrofit+Okhttp 在 Android 中是不是默认使用 httpCaching?