资讯专栏INFORMATION COLUMN

Android网络编程之9Retrofit2前篇[基本使用]

Nosee / 1521人阅读

摘要:创建增加返回值为的支持这里的加上之前定义的参数形成完整的请求地址用于指定返回的参数数据类型,这里我们支持和类型。完整的代码如下增加返回值为的支持请求参数上文讲了访问网络的基本方法,接下来我们来了解下常用的请求参数。

前言

Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,而OkHttp现在已经得到Google官方认可,不了解OKHttp的请查看本系列的前作。

1.使用前准备

老生长谈,先配置build.gradle:

dependencies {
  ...
    compile "com.squareup.retrofit2:retrofit:2.1.0"
    compile "com.squareup.retrofit2:converter-gson:2.1.0"
    compile "com.squareup.retrofit2:converter-scalars:2.1.0"//ConverterFactory的String依赖包
}

当然别忘了在manifest加入访问网络的权限:

这次我们访问的网站产生了变化,我们用淘宝ip库,里面有访问接口的说明:
1. 请求接口(GET):
/service/getIpInfo.php?ip=[ip地址字串]

2. 响应信息:
(json格式的)国家 、省(自治区或直辖市)、市(县)、运营商

3. 返回数据格式:

{
    “code”: 0,
    ”data”: {
        “ip”: ”210.75.225.254”,
        ”country”: ”u4e2du56fd”,
        ”area”: ”u534eu5317”,
        “region”: ”u5317u4eacu5e02”,
        ”city”: ”u5317u4eacu5e02”,
        ”county”: ”“,
        ”isp”: ”u7535u4fe1”,
        “country_id”: ”86”,
        ”area_id”: ”100000”,
        ”region_id”: ”110000”,
        ”city_id”: ”110000”,
        “county_id”: ”-1”,
        ”isp_id”: ”100017”
    }
}

其中code的值的含义为,0:成功,1:失败。

2.用Retrofit异步访问网络 编写实体类

我们可以用JSON字符串转换成Java实体类(POJO)这个网站将Json转为实体类,经过修改的实体类如下:

IpModel.java:

public class IpModel {
    private int code;
    private IpData data;
    public void setCode(int code) {
        this.code = code;
    }
    public int getCode() {
        return this.code;
    }
    public void setData(IpData data) {
        this.data = data;
    }
    public IpData getData() {
        return this.data;
    }
}

IpData.java:

public class IpData {
    private String country;
    private String country_id;
    private String area;
    private String area_id;
    private String region;
    private String region_id;
    private String city;
    private String city_id;
    private String county;
    private String county_id;
    private String isp;
    private String isp_id;
    private String ip;
    public void setCountry(String country) {
        this.country = country;
    }
    public String getCountry() {
        return this.country;
    }
    public void setCountry_id(String country_id) {
        this.country_id = country_id;
    }
    ...
 }
请求网络接口
public interface IpService{
    @GET("getIpInfo.php")
    Call getIpMsg(@Query("ip")String ip);
}

Retrofit提供的请求方式注解有@GET和@POST等,分别代表GET请求和POST请求,我们在这里访问的界面是“getIpInfo.php”。参数注解有@PATH和@Query等,@Query就是我们的请求的键值对的设置,在这里@Query("ip")代表键,“String ip”则代表值。

创建Retrofit
   String url = "http://ip.taobao.com/service/";
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                //增加返回值为String的支持
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

这里的baseUrl加上之前@GET("getIpInfo.php")定义的参数形成完整的请求地址;addConverterFactory用于指定返回的参数数据类型,这里我们支持String和Gson类型。

用Retrofit创建接口文件
 IpService ipService = retrofit.create(IpService.class);
 Callcall=ipService.getIpMsg(ip);

用retrofit创建我们之前定义的IpService接口对象,并调用该接口定义的getIpMsg方法得到Call对象。

用Call请求网络并处理回调
 call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
               String country= response.body().getData().getCountry();
                Log.i("wangshu","country"+country);
                Toast.makeText(getApplicationContext(),country,Toast.LENGTH_SHORT).show();
            }

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

            }
        });

这里是异步请求网络,回调的Callback是运行在主线程的。得到返回的Response后将返回数据的country字段用Toast显示出来。如果想同步请求网络请使用 call.execute(),如果想中断网络请求则可以使用 call.cancel()。

完整的代码如下:

public class MainActivity extends AppCompatActivity {
    private Button bt_request;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt_request = (Button) findViewById(R.id.bt_request);
        bt_request.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getIpInformation("59.108.54.37");
            }
        });
    }

    private void getIpInformation(String ip) {
        String url = "http://ip.taobao.com/service/";
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                //增加返回值为String的支持
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        IpService ipService = retrofit.create(IpService.class);
        Callcall=ipService.getIpMsg(ip);
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
               String country= response.body().getData().getCountry();
                Log.i("wangshu","country"+country);
                Toast.makeText(getApplicationContext(),country,Toast.LENGTH_SHORT).show();
            }

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

            }
        });
    }
3.请求参数

上文讲了Retrofit访问网络的基本方法,接下来我们来了解下Retrofit常用的请求参数。

请求方法

请求方法除了上文讲到的@GET,还有@POST、@PUT、@DELETE、@HEAD、@OPTIONS、@PATCH、@HTTP。其中@HTTP用来替换以上7个,其他的分别对应着不同的请求方法,不明白的请查看Android网络编程(一)HTTP协议原理这一篇文章。

@Query

前面的例子就用了Query用来查询参数。

public interface IpService{
    @GET("getIpInfo.php")
    Call getIpMsg(@Query("ip")String ip);
}
@QueryMap

如果Query参数比较多,那么可以通过@QueryMap方式将所有的参数集成在一个Map统一传递。

public interface BlueService {
    @GET("book/search")
    Call getSearchBooks(@QueryMap Map options);
}
@Path

@Path用来替换路径。

public interface ApiStores {
    @GET("adat/sk/{cityId}.html")
    Call getWeather(@Path("cityId") String cityId);
}
@Body

@Body与@POST注解一起使用,提供查询主体内容,其中ApiInfo是一个bean类。

public interface ApiStores {
        @POST("client/shipper/getCarType")
        Call getCarType(@Body ApiInfo apiInfo);
    }
@Headers
interface SomeService {
 @GET("some/endpoint")
 @Headers("Accept-Encoding: application/json")
 Call getCarType();
}

@Headers用来添加头部信息,上面用的是固定头部,也可以采用动态头部:

interface SomeService {
 @GET("some/endpoint")
 Call someEndpoint(
 @Header("Location") String location);
}
@Multipart

@Multipart用来上传文件

public interface FileUploadService {  
    @Multipart
    @POST("upload")
    Call upload(@Part("description") RequestBody description,
                              @Part MultipartBody.Part file);
}

github源码下载

参考资料
Retrofit 2.0文件上传
RxJava 与 Retrofit 结合的最佳实践
Retrofit2使用初探
android 介绍Retrofit的简单使用
Retrofit框架使用笔记
Retrofit 解析 JSON 数据
用 Retrofit 2 简化 HTTP 请求
Android Retrofit 2.0使用

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70585.html

相关文章

  • Android网络编程7源码解析OkHttp前篇[请求网络]

    摘要:异步请求当正在运行的异步请求队列中的数量小于并且正在运行的请求主机数小于时则把请求加载到中并在线程池中执行,否则就再入到中进行缓存等待。通常情况下拦截器用来添加,移除或者转换请求或者响应的头部信息。 前言 学会了OkHttp3的用法后,我们当然有必要来了解下OkHttp3的源码,当然现在网上的文章很多,我仍旧希望我这一系列文章篇是最简洁易懂的。 1.从请求处理开始分析 首先OKHttp...

    blastz 评论0 收藏0
  • Android网络编程10Retrofit2后篇[请求参数]

    摘要:前言在上一篇网络编程九前篇基本使用中我们了解了的最基本的方式访问网络的写法以及请求参数的简单介绍。在这里我们仍旧访问淘宝库。可以看到请求数据是一个字符串,因为淘宝库并不支持此类型所以不会返回我们需要的地理信息数据。 前言 在上一篇[Android网络编程(九)Retrofit2前篇[基本使用]](http://www.jianshu.com/p/c383...中我们了解了Retrofi...

    nihao 评论0 收藏0
  • Swoole协程旅-前篇

    摘要:协程完全有用户态程序控制,所以也被成为用户态的线程。目前支持协程的语言有很多,例如等。协程之旅前篇结束,下一篇文章我们将深入分析原生协程部分的实现。 写在最前   Swoole协程经历了几个里程碑,我们需要在前进的道路上不断总结与回顾自己的发展历程,正所谓温故而知新,本系列文章将分为协程之旅前、中、后三篇。 前篇主要介绍协程的概念和Swoole几个版本协程实现的主要方案技术; 中篇主...

    terasum 评论0 收藏0

发表评论

0条评论

Nosee

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<