Retrofit的简单用法

最近在啃retrofit和Rx_Java,以现在的水平只能说是略懂皮毛,只会简单使用,但是尽管懂得少,我也要继续写下去,我相信一直坚持下去总会有收获。

1.Retrofit的使用
先来说一下大概的需求,就是输入百度网址,拿到返回的body
首先需要给项目定义一个接口,用于后边的发送请求。

public interface Service {
    @GET("/")//用来写子目录
    Call<String> getBaidu();
}

这里我们先采用get方法发送网络请求,@GET为retrofit的注解,后边的注释是用于写子目录的。如何理解这个呢,你想要在百度上搜索“图片”两个关键字,点击enter键,会出现搜索结果,这时候浏览器上的IP地址已经变成了“https://www.baidu.com/xxxxxxx”在这里retrofit将网址url分成两部分“www.baidu.com”作为baseURL,斜杠后面的作为子目录。
再来看一下 getBaidu()方法,由于这里声明的是接口,所以没有方法体,但是其返回类型是retrofit里的Call类型,泛型为拿到String,这里泛型可以自己改,根据你拿到网络数据以后,想要对他做如何的处理,现在的需求只是拿到返回体
接下来开始使用retrofit对象生成实体,并访问网络,代码如下:

 Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.baidu.com")
                .addConverterFactory(
                        new Converter.Factory() {
                            @Nullable
                            @Override
                            public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
                                return new Converter<ResponseBody, String>() {
                                    @Override
                                    public String convert(ResponseBody value) throws IOException {
                                        return value.string();
                                    }
                                };
                            }
                        }
                ).build();

从上面代码可以看出,Retrofit是通过build方式来创建对象的。咱们一行一行的来看代码baseURL方法是为retrofit添加基本网址,前面已经介绍过了。
由于我们访问网络以后拿到的数据可能多样,可能是二进制流或者网络请求回调,在这里我们利用addConverterFactory方法对拿到的返回体进行转化,在后边实战过程中这段代码不需要我们自己写。这次我们将返回体的内容转化为string
build方法建立实体对象。
接下来利用retrofit的Call将任务分发出去并执行。代码如下

 Service service = retrofit.create(Service.class);//通过接口代理,创建service实例
        Call<String> call = service.getBaidu();
        call.enqueue(this);

后边将activity实现Callback<String>接口,并复写两个方法

@Override
    public void onResponse(Call<String> call, Response<String> response) {
        tv.setText(response.body());
    }

    @Override
    public void onFailure(Call<String> call, Throwable t) {

    }

在onResponse方法里可以将拿到的string对象显示在UI上面。
Activity的整体代码如下:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Converter;
import retrofit2.Response;
import retrofit2.Retrofit;

public class MainActivity extends AppCompatActivity implements Callback<String> {
    TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv);
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.baidu.com")
                .addConverterFactory(
                        new Converter.Factory() {
                            @Nullable
                            @Override
                            public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
                                return new Converter<ResponseBody, String>() {
                                    @Override
                                    public String convert(ResponseBody value) throws IOException {
                                        return value.string();
                                    }
                                };
                            }
                        }
                ).build();
        Service service = retrofit.create(Service.class);//通过接口代理,创建service实例
        Call<String> call = service.getBaidu();
        call.enqueue(this);

    }

    @Override
    public void onResponse(Call<String> call, Response<String> response) {
        tv.setText(response.body());
    }

    @Override
    public void onFailure(Call<String> call, Throwable t) {

    }
}

xml文件很简单就一个textview,这里就不再写
2.用retrofit来解析json数据
这里用的是视频教程里的API接口,但是API有点久远无法使用,代码是没问题的。简单来说一下吧。
首先是Service接口

public interface Service {
    /*
    * get请求
    * */
//    @GET("/api/{category}/list")
//    Call<Tngou> getList(@Path("category")String category,@Query("id") int id, @Query("page") int page, @Query("rows")int rows);//请求参数写在括号里
    /*
    * post请求
    * */
    @POST("/api/{category}/list")
    Call<Tngou> getList(@Path("category")String category, @Field("id") int id, @Field("page") int page, @Field("rows") int rows);//请求参数写在括号里

链接为变化的,假如对于一个api连接而言有很多种类,有食谱,新闻,微信头条文章,他们对应的API子目录可能是“/api/cook/list”,“/api/news/list”,“/api/weixin/list”大家可以看到这三个API对应的连接就中间的发生了变化,其他的没有变。这时候retrofit为解决代码复用问题添加了@path注解可以动态变换ip。另外还有请求参数,用@Query来注解。
下面的是post请求,就是注解需要换一下,其他的都一样,不再解释。
在这里需要注意的是返回类型 Call<Tngou>,泛型为Tngou,这个泛型是自己定义的,相当于gson对应的Javabean。

import com.google.gson.annotations.SerializedName;

import java.util.List;

/**
 * Created by 上官若枫 on 2017/9/19.
 */

public class Tngou {
    //使用注解让类的属性命名更加友好
    @SerializedName("status")
    private boolean status;
    @SerializedName("total")
    private int total;
    @SerializedName("tngou")
    private List<Cook>list;

    public boolean isStatus() {
        return status;
    }

    public void setStatus(boolean status) {
        this.status = status;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public List<Cook> getList() {
        return list;
    }

    public void setList(List<Cook> list) {
        this.list = list;
    }
}

javabean 里面有一个@SerializedName注解,这个呢会让属性命名更加友好,啥意思??假如json数据流里面写的是属性是“n”代表name,那你在写对应的Javabean里面写n就不合适了,加上这个注解,你的命名可以随便写。
下面是activity的代码

public class MainActivity extends AppCompatActivity implements Callback<Tngou> {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.tngou.net")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        Service service = retrofit.create(Service.class);
        Call<Tngou> call = service.getList("cook",0,1,20);
        call.enqueue(this);
    }

    @Override
    public void onResponse(Call<Tngou> call, Response<Tngou> response) {
        List<Cook> list = response.body().getList();
    }

    @Override
    public void onFailure(Call<Tngou> call, Throwable t) {

    }
}

这里面的addConverterFactory方法里不需要我们自己写了,直接用retrofit的gson解析,利用retrofit.create(Service.class);创造实体类,然后调用.getList方法将参数输入进去。在 onResponse方法里面拿到结果并进行处理。
感兴趣的同学可以关注一下我的微信公众号,或者微信搜索 开发 Android的小学生

qrcode_for_gh_c686d73be7e1_430.jpg
qrcode_for_gh_c686d73be7e1_430.jpg
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值