retrofit 2.0 简单使用

来源:互联网 发布:浪潮软件论坛 编辑:程序博客网 时间:2024/05/29 11:45

Retrofit与okhttp都是出于Square公司,Retrofit对okhttp做了一层包装,把网络请求都交给了okhttp(可以参考okhttp3使用),因此只需要简单的配置,就能用Retrofit进行网络请求。

一、引入retrofit 2.0

需要在项目下的build.gradle添加retrofit 2.0.2的引用

// retrofit 库compile 'com.squareup.retrofit2:retrofit:2.0.2'// 使用gson解析数据内容compile 'com.squareup.retrofit2:converter-gson:2.0.2'

这里写图片描述

如上图所示,引入retrofit 2.0.2后,会在External Libraries中看到retrofit-2.0.2okhttp-3.2.0okio-1.6.0,这是因为retrofit 2.0.2封装了okhttp-3.2.0,而okhttp-3.2.0又依赖于okio-1.6.0,因此引入一个retrofit库,会自动添加其依赖的其他库。

二、retrofit 2.0 基本使用

1、retrofit对象创建

Retrofit retrofit = new Retrofit.Builder()                                // 设置基本url,通常是协议+IP地址+端口                                .baseUrl(API_URL)                                // 设置数据解析的格式,需要引入gson库                                 .addConverterFactory(GsonConverterFactory.create())                                .build();

2、retrofit网络请求接口

retrofit将Http Api使用Java接口表示;

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

每一个Call对象从GitHub接口里的方法获取,Call基于Http的同步/异步方法想服务端获取请求结果。

Call<List<Contributor>> call = github.contributors("square", "retrofit");

3、动态设置url的Get方法

retrofit 2.0允许动态设置 URL,需要使用一对大括号{}将需要动态替换的URL内容括起来,对应的参数使用相同的字符串,同时使用@Path注解表示。

如,需要请求这个地址(https://api.github.com/repos/square/retrofit/contributors)的数据,可以添加请求接口:

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

在实际调用的时候,传入正确的参数便可

Call<List<Contributor>> call = github.contributors("square", "retrofit");

这里给出完整的动态设置Url的同步调用Get方法源码;

/** * 同步方法 */private void btn_synchronous_dynamically_getMethod() {    try {        new Thread(new Runnable() {            @Override            public void run() {                try {                    // Create a very simple REST adapter which points the GitHub API.                    Retrofit retrofit = new Retrofit.Builder()                            // 设置基本url,通常是协议+IP地址+端口                            .baseUrl(API_URL)                            // 设置数据解析的格式,需要引入gson库                            .addConverterFactory(GsonConverterFactory.create())                            .build();                    // Create an instance of our GitHub API interface.                    GitHub github = retrofit.create(GitHub.class);                    // Create a call instance for looking up Retrofit contributors.                    Call<List<Contributor>> call = github.contributors("square", "retrofit");                    // Fetch and print a list of the contributors to the library.                    List<Contributor> contributors = call.execute().body();                    final StringBuilder sb = new StringBuilder();                    for (Contributor contributor : contributors) {                        sb.append(contributor.getLogin() + " (" + contributor                                .getContributions() + ")\n");                    }                    Log.i(TAG, "tht synchronous function run on thread id is " + Thread                            .currentThread().getId());                    Log.i(TAG, sb.toString());                    runOnUiThread(new Runnable() {                        @Override                        public void run() {                            mToast.setText(sb.toString());                            mToast.show();                        }                    });                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();    } catch (Exception e) {        e.printStackTrace();    }}

注:Android 4.0之后,不允许网络请求在主线程中使用。

异步方法通过在Call的enqueue中添加结果回调来完成。如果需要获取Http原始的Response对象,使用Response raw = response.raw();

/** * 异步方法 */private void btn_asynchronous_dynamically_getMethod() {    // Create a very simple REST adapter which points the GitHub API.    Retrofit retrofit = new Retrofit.Builder()            .baseUrl(API_URL)            .addConverterFactory(GsonConverterFactory.create())            .build();    // Create an instance of our GitHub API interface.    GitHub github = retrofit.create(GitHub.class);    // Create a call instance for looking up Retrofit contributors.    Call<List<Contributor>> call = github.contributors("square", "retrofit");    // Fetch and print a list of the contributors to the library.    call.enqueue(new Callback<List<Contributor>>() {        @Override        public void onResponse(Call<List<Contributor>> call, Response<List<Contributor>>                response) {            try {                // get raw response                // Response raw = response.raw();                Log.i(TAG, "tht callback function run on thread id is " + Thread                        .currentThread().getId());                StringBuilder sb = new StringBuilder();                List<Contributor> contributors = response.body();                for (Contributor contributor : contributors) {                    sb.append(contributor.getLogin() + " (" + contributor                            .getContributions() + ")\n");                }                mToast.setText(sb.toString());                mToast.show();                Log.i(TAG, sb.toString());            } catch (Exception e) {                e.printStackTrace();            }        }        @Override        public void onFailure(Call<List<Contributor>> call, Throwable t) {        }    });}

4、retrofit 查询参数

4.1、一个参数查询

如果只有一个查询参数的Get/Post请求,可以使用Query注解;
比如针对链接(http://api.k780.com:88/?app=weather.future)请求,需要设置java请求接口为:

    @POST("/")    Call<WeatherList> getWeatherForAQuery(@Query("app") String queryParams);

注:参数查询不能使用@POST(“/app={param}”),然后通过@Path注解动态传递数值。

4.2、多个参数查询

如果查询参数有多个,需要使用QueryMap注解,参数通过Map<String,String>对象传递。当然,也可以只使用Query注解,不过需要添加多个Query注解才行;

public interface YourInterface {    @GET("your-url")    Call<responsebody> postcode(@Query("op") String op, @Query("postcode") String postcode);}

下面演示对天气Url(http://api.k780.com:88/?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json)数据请求;

定义请求天气的Java接口,如果是用Get请求,需要将@POST改成@GET,需要用到的WeatherList对象,可以再文章的最后下载demo;

public interface WeatherApi {    @POST("/")    Call<WeatherList> getWeatherForQueryMap(@QueryMap Map<String,String> options);}

注:注解括号内容不能为空,即使baseUrl写成http://api.k780.com:88/,注解也不能为 @POST(“”),否则运行出错。

最终调用方法;

private void btn_asynchronous_queryParamete_getMethod() {    try {        Retrofit retrofit = new Retrofit.Builder().baseUrl("http://api.k780.com:88/")                .addConverterFactory(GsonConverterFactory.create()).build();        Map<String, String> options = new HashMap<String, String>();        options.put("app", "weather.future");        options.put("weaid", "1");        options.put("appkey", "10003");        options.put("sign", "b59bc3ef6191eb9f747dd4e83c99f2a4");        options.put("format", "json");        Call<WeatherList> result = retrofit.create(WeatherApi.class).getWeather2(options);        result.enqueue(new Callback<WeatherList>() {            @Override            public void onResponse(Call<WeatherList> call, Response<WeatherList> response) {                Log.i("MainActivity", new Gson().toJson(response.body()));            }            @Override            public void onFailure(Call<WeatherList> call, Throwable t) {            }        });    } catch (Exception e) {        e.printStackTrace();    }}
4.3、同名的多个查询参数

有些情况下通过同名的多个参数请求,比如https://api.example.com/tasks?id=123&id=124&id=125 ,由于参数数据类型是一样的,可以通过List<>组合多个参数;

public interface TaskService {      @GET("/tasks")    Call<List<Task>> getTask(@Query("id") List<Long> taskIds);}

5、发送json参数

当请求参数是个JSON字符串,可以使用@Body注解一个对象,Retrofit可以将一个对象转化为JSON字符串;

定义一个对象;

public class Task {      private long id;    private String text;    public Task(long id, String text) {        this.id = id;        this.text = text;    }}

声明请求数据接口;

public interface TaskService {      @POST("/tasks")    Call<Task> createTask(@Body Task task);}

调用方法;

Task task = new Task(1, "my task title");  Call<Task> call = taskService.createTask(task);  call.enqueue(new Callback<Task>() {}); 

调用createTask方法,把task对象的属性转化为JSON形式,对应的task参数实际为

{    "id": 1,    "text": "my task title"}

5、文件上传

retrofit的文件上传,需要使用@Multipart注解;

文件上传接口定义;

public interface FileUploadService {    public static final String BASE_URL = "http://your.api/endpoint/base-url";    @Multipart    @POST("/upload")    void upload(@Part("myfile") TypedFile file,                @Part("description") String description,                Callback<String> cb);}

定义call对象模板;

public class ServiceGenerator {    public static final String API_BASE_URL = "http://your.api-base.url";    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();    private static Retrofit.Builder builder =            new Retrofit.Builder()                    .baseUrl(API_BASE_URL)                    .addConverterFactory(GsonConverterFactory.create());    public static <S> S createService(Class<S> serviceClass) {        Retrofit retrofit = builder.client(httpClient.build()).build();        return retrofit.create(serviceClass);    }}

实际调用;

FileUploadService service = ServiceGenerator.createService(FileUploadService.class, FileUploadService.BASE_URL);TypedFile typedFile = new TypedFile("multipart/form-data", new File("path/to/your/file"));String description = "hello, this is description speaking";service.upload(typedFile, description, new Callback<String>() {    @Override    public void success(String s, Response response) {        Log.e("Upload", "success");    }    @Override    public void failure(RetrofitError error) {        Log.e("Upload", "error");    }});

TypedFileRetrofit中定义,提供Filemime type两个参数,这里使用的mime type值为multipart/form-data

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机后面贴的膜都是胶怎么办 车漆外面一层保护膜被划开了怎么办 美团骑手gps信号弱时怎么办 华为荣耀4x充电插口坏了怎么办 华为畅享5s开不了机怎么办 华为梅特10忘记账号密码怎么办 华为荣耀8充电接口坏了怎么办 华为手机锁屏了自动开屏怎么办 支付宝收货地址写错了怎么办 支付宝领海报地址写错了怎么办 手机总是弹出日历已停止运行怎么办 华为mate8忘了锁屏密码怎么办 红米4a打王者卡怎么办 苹果5s软件更新密码忘记了怎么办 华为荣耀P9进水了没有声音怎么办 华为荣耀7原相机不能拍照怎么办 华为手机触屏密码忘记了怎么办 华为荣耀10屏锁密码忘了怎么办 华为手机开机卡在开机界面怎么办 苹果6s国行不能用移动4g怎么办 苹果手机32g内存不够用怎么办 华为荣耀6x忘记了密码怎么办 百度粉色衣服被洗变色了怎么办 粉色衣服放进洗衣机洗变色了怎么办 红米note5a应用锁忘了怎么办 索尼手机死机了怎么办不可拆卸电池 华为手机一直停留在开机画面怎么办 5s用11.4太卡了怎么办 华为荣耀5a手机声音小怎么办 牙签卡在手机插卡针里怎么办 捡的华为手机账号激活不了怎么办 华为平板激活手机密码忘了怎么办 捡个华为手机非要激活才能用怎么办 华为手机没激活想重新激活怎么办 华为手机激活总显示系统繁忙怎么办 华为荣耀7i进水了不开机怎么办 华为荣耀手机进水了怎么办开不开机 华为畅享5s变砖怎么办 我的苹果7机身内存满了怎么办 小米5x拆机后屏幕翘边怎么办 苹果手机设备禁止游戏登入怎么办