Android网络请求框架之Retrofit

Posted ykb19891230

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android网络请求框架之Retrofit相关的知识,希望对你有一定的参考价值。

如未接触过Retrofit,请先看以下内容:
1.Android网络请求框架之Retrofit(一)
2.Android网络请求框架之Retrofit(二)

第一篇文章我们讲述了Retrofit的基本用法,让大家对Retrofit有了一定的认识,第二篇文章讲述了Rx模式和Retrofit结合的用法,让大家接触Rx模式和进一步了解Retrofit。下面我将为大家讲述Retrofit1.9.0版本和2.0.0版本API的差异。

同步请求

Retrofit1

public interface TaskService   
    @GET("/tasks")
    List<Task> getTasks();

Retrofit2

public interface TaskService   
    @GET("/tasks")
    Call<List<Task>> getTasks();

可以很清楚的看出他们的区别:1.9.0版本,数据直接通过方法的返回值获取,2.0.0版本则是把数据包装到Call对象里。同步方法实在主线程执行的,所以在android4.0及以上版本会抛出NetworkOnMainThreadException异常,所以在调用的时候要自己放到子线程里去执行,然后通过Handler更新界面。

同步方法里获取数据

Retrofit1

TaskService taskService = ServiceGenerator.createService(TaskService.class);  
List<Task> tasks = taskService.getTasks(); 

Retrofit2

TaskService taskService = ServiceGenerator.createService(TaskService.class);  
Call<List<Task>> call = taskService.getTasks();  
List<Task>> tasks = call.execute().body(); 

异步请求

Retrofit1

public interface TaskService   
    @GET("/tasks")
    void getTasks(Callback<List<Task>> cb);

Retrofit2

public interface TaskService   
    @GET("/tasks")
    Call<List<Task>> getTasks();

可以看到,同步和异步请求在2.0.0版本是一样的,1.9.0才有所区别,但是这针对的是请求,数据获取还是有所区别的。

异步方法里获取数据

Retrofit1

TaskService taskService = ServiceGenerator.createService(TaskService.class);  
taskService.getTasks(new Callback<List<Task>>()   
    @Override
    public void success(List<Task> tasks, Response response) 
        // here you do stuff with returned tasks
    

    @Override
    public void failure(RetrofitError error) 
        // you should handle errors, too
    
);

Retrofit2

TaskService taskService = ServiceGenerator.createService(TaskService.class);  
Call<List<Task>> call = taskService.getTasks();  
call.enqueue(new Callback<List<Task>>()   
    @Override
    public void onResponse(Call<List<Task>> call, Response<List<Task>> response) 
        if (response.isSuccess()) 
            // tasks available
         else 
            // error response, no access to resource?
        
    

    @Override
    public void onFailure(Call<List<Task>> call, Throwable t) 
        // something went completely south (like no internet connection)
        Log.d("Error", t.getMessage());
    

对于异步方法来说,我们最后都必须传入一个Callback接口,实现它的success方法和onFailure方法,不同的是,1.9.0的Callback作为一个参数传递到方法里,2.0.0先返回一个Call对象,再调用Call对象的enqueue方法,传入Callback对象去获取数据。

请求载体的区别

Retrofit1

 public synchronized RestAdapter build(final String url) 
        //这就是发起请求的对象
        RestAdapter adapter = null==adapters.get(url)?null:adapters.get(url).get();
        if (null == adapter) 
            final CellInfo cellInfo = Utils.getCellInfo();
            //添加一些header
            RequestInterceptor requestInterceptor = new RequestInterceptor() 
                @Override
                public void intercept(RequestFacade request) 
                    request.addHeader("Authorization", String.format("Bearer %s", MainApp.getToken()));

                    request.addHeader("LoyoPlatform", cellInfo.getLoyoPlatform());
                    request.addHeader("LoyoAgent", cellInfo.getLoyoAgent());
                    request.addHeader("LoyoOSVersion", cellInfo.getLoyoOSVersion());
                    request.addHeader("LoyoVersionName", Global.getVersionName());
                    request.addHeader("LoyoVersionCode", String.valueOf(Global.getVersion()));
                
            ;
    //指定url,设置log级别,设置拦截器。。。。。。
            adapter = new RestAdapter.Builder().setEndpoint(url).setLogLevel(RestAdapter.LogLevel.FULL).setRequestInterceptor(requestInterceptor).build();
            adapters.put(url, new SoftReference<>(adapter));
        

        return adapter;
    

Retrofit2

public synchronized <S> S create(Class<S> serviceClass, final String token) 
        httpClient.interceptors().clear();
        if (token != null) 
            httpClient.interceptors().add(new Interceptor() 
                @Override
                public Response intercept(Chain chain) throws IOException 
                    Request original = chain.request();

                    Request.Builder requestBuilder = original.newBuilder()
//                            .header("Accept", "applicaton/json")
                            .header("AccessToken", token);
//                            .method(original.method(), original.body());

                    Request request = requestBuilder.build();
                    return chain.proceed(request);
                
            );
        
        //请求发起者
        Retrofit retrofit = builder.client(httpClient).build();
        return retrofit.create(serviceClass);
    

1.9.0的请求发起者是RestAdapter,2.0.0的直接就叫Retrofit。并且在设置header和log级别上也有所差异。1.9.0可以再builder里直接指定log级别,2.0.0需要引入compile 'com.squareup.okhttp:logging-interceptor:2.6.0' 这个库来设置log级别,当然,也可以自己实现Interceptor来自定义日志输出

 class LoggingInterceptor implements Interceptor 

        @Override
        public Response intercept(Chain chain) throws IOException 
            Request request = chain.request();

            long t1 = System.nanoTime();
            String requestLog = String.format("Sending request %s on %s%n%s",
                    request.url(), chain.connection(), request.headers());
            //YLog.d(String.format("Sending request %s on %s%n%s",
            //        request.url(), chain.connection(), request.headers()));
            if (request.method().compareToIgnoreCase("post") == 0) 
                requestLog = "\\n" + requestLog + "\\n" + bodyToString(request);
            
            Log.d("TAG", "request" + "\\n" + requestLog);

            Response response = chain.proceed(request);
            long t2 = System.nanoTime();

            String responseLog = String.format("Received response for %s in %.1fms%n%s",
                    response.request().url(), (t2 - t1) / 1e6d, response.headers());

            String bodyString = response.body().string();

            Log.d("TAG", "response" + "\\n" + responseLog + "\\n" + bodyString);

            return response.newBuilder()
                    .body(ResponseBody.create(response.body().contentType(), bodyString))
                    .build();
        

        private String bodyToString(final Request request) 
            try 
                final Request copy = request.newBuilder().build();
                final Buffer buffer = new Buffer();
                copy.body().writeTo(buffer);
                return buffer.readUtf8();
             catch (final IOException e) 
                return "did not work";
            
        
    

当然,Retrofit1.9.0和2.0.0的区别远远不止这些,比如2.0.0版本引入的库比1.9.0要多很多,但是他们最直观的区别应该就是2.0.0完全采用函数式编程思想来实现,即使代码数量过多,也可以很好地控制代码结构和理清代码逻辑,从这点来说,2.0.0还是我比较喜欢的。期待大家去发掘更多的新奇用法。

以上是关于Android网络请求框架之Retrofit的主要内容,如果未能解决你的问题,请参考以下文章

Android网络请求框架之Retrofit

Android 网络请求框架之Retrofit 的 详细使用

Android 网络请求框架之Retrofit 的 详细使用

Android 网络请求框架之Retrofit 的 详细使用

Android 网络请求框架之Retrofit 的 详细使用

android之Retrofit使用