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还是我比较喜欢的。期待大家去发掘更多的新奇用法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值