什么是 Retrofit ?

Retrofit 是一套 RESTful 架构的 Android(Java) 客户端实现,基于注解,提供 JSON to POJO(Plain Ordinary Java Object ,简单 Java 对象),POJO to JSON,网络请求(POST,GET, PUT,DELETE 等)封装。

既然只是一个网络请求封装库,现在已经有了那么多的大家已经耳熟能详的网络请求封装库了,为什么还要介绍它呢,原因在于 Retrofit 是一套注解形的网络请求封装库,让我们的代码结构更给为清晰。它可以直接解析JSON数据变成JAVA对象,甚至支持回调操作,处理不同的结果。
想更详细的了解 Retrofit,可以查看官方文档 。

话不多说,直入主题~~

一、集成

目前我使用的是AndroidStudio,那么在model的build.gradle文件中添加以下引用:

compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'

说明:

Retrofit依赖于okhttp,所以需要集成okhttp
API返回的数据为JSON格式,在此我使用的是Gson对返回数据解析.请使用最新版的Gson

二、返回的数据格式

使用的是百度API的数据接口:名人名言API

QQ截图20160315114933.png QQ截图20160315115050.png

该接口的API主机地址为:http://apistore.baidu.com;
需要访问的接口:avatardata/mingrenmingyan/lookup;

需要一个key等于apikey的Header和一个keyword等于名人名言的查询关键字,而且该请求为GET请求.

访问该API返回的数据格式如下:

{    "total": 914,    "result": [        {            "famous_name": "布兰登",            "famous_saying": "人生至善,就是对生活乐观,对工作愉快,对事业兴奋。"        },        {            "famous_name": "魏书生",            "famous_saying": "抽打自己的鞭子要掌握在自己的手里,在漫长的人生道路的每一步上,都要经常鞭策自警,万不可以为有过一两次抽打就可以沿途平安了。"        },        {            "famous_name": "亨·易卜生",            "famous_saying": "夺走了普通人生活的幻想,也就等于夺去了他的幸福"        },        {            "famous_name": "佚名",            "famous_saying": "不知道自己走向何方的人,大都是人生的匆匆过客。"        },        {            "famous_name": "南丁格尔",            "famous_saying": "人生欲求安全,当有五要。一是清洁空气,二是澄清饮水,三是流通沟渠,四是扫洒屋宇,五是日光充足。"        }    ],    "error_code": 0,    "reason": "Succes"}

三、AndroidStudio插件 GsonFormat

我们根据上面API返回的json数据来创建一个FamousInfo数据对象,我们可以利用AndroidStudio插件 GsonFormat 快速,方便的将json数据转为Java 对象,
FamousInfo.java

package com.woyou.androidsample.bean;import java.util.List;/** * Created by Xiho on 2016/3/14. */public class FamousInfo {    /**     * total : 227     * result : [{"famous_name":"车尔尼雪夫斯基","famous_saying":"非凡的单纯,非凡的明确\u2014\u2014这是天才的智慧的最可惊人的品质。"},{"famous_name":"约·德莱顿","famous_saying":"天才在社会生活中往往显得迟钝而"},{"famous_name":"雨果","famous_saying":"敢于冲撞命运才是天才"},{"famous_name":"卡莱尔","famous_saying":"所谓天才,就是比任何人都先抵挡痛苦的经验本领。"},{"famous_name":"林肯","famous_saying":"卓越的天才不屑走一条人家走过的路。他寻找迄今没有开拓过的地区。"},{"famous_name":"席勒","famous_saying":"产生天才的土壤比天才还要难找"},{"famous_name":"爱因斯坦","famous_saying":"任何天才不能在孤独的状态中发展"},{"famous_name":"民谚","famous_saying":"名人的古怪行为是天才的标志,凡人的古怪行为是神经出了毛病"},{"famous_name":"鲁迅","famous_saying":"哪里有天才,我是把别人喝咖啡的工夫都用在了工作上了。"},{"famous_name":"塞涅夫","famous_saying":"没有某些发狂的劲头,就没有天才。"},{"famous_name":"狄德罗","famous_saying":"精神的浩瀚想象的活跃心灵的勤奋:就是天才。"},{"famous_name":"爱默生","famous_saying":"平凡的人希望,天才的人创造。"},{"famous_name":"契诃夫","famous_saying":"真正的天才是常常隐藏在群众里面,绝不挤向人前去露脸的。"},{"famous_name":"别林斯基","famous_saying":"任何天才,不经过艰苦不断的劳动,不经过最使空想家头疼和懊恼的最初纯物质和机械的劳动,就无法精通任何种类的艺术。"},{"famous_name":"杨格","famous_saying":"我愿意以天才比美德,以学问比财富。如美德越少的人,越需要财富,天才越低的人,越需要学问。"},{"famous_name":"巴尔扎克","famous_saying":"职业尽管不同,但天才的品德并无分别。"},{"famous_name":"恩格斯","famous_saying":"逆境使天才脱颖而出,顺境会埋没"},{"famous_name":"巴尔扎克","famous_saying":"破坏的人和建设的人,两者都是意志的现象:一个是准备工作,另一个是完成工作;前者好像是一个恶的天才,后者似乎是一个善的天才;对这一个给予光荣,对另一个给予忘却。恶者哇啦哇啦,把庸俗的人们从梦里惊醒,对他佩服得五体投地,可是善者却一直默不作声。"},{"famous_name":"培根","famous_saying":"如果孩子确有某种超群的天才,那当然应该扶植发展。但就一般情况说,下面这句格言很有用的:\u201c长期的训练会通过适应化难为易。\u201d"},{"famous_name":"爱迪生","famous_saying":"天才是百分之一的灵感,百分之九十九的血汗。"}]     * error_code : 0     * reason : Succes     */    private int total;    private int error_code;    private String reason;    /**     * famous_name : 车尔尼雪夫斯基     * famous_saying : 非凡的单纯,非凡的明确——这是天才的智慧的最可惊人的品质。     */    private List result;    public void setTotal(int total) {        this.total = total;    }    public void setError_code(int error_code) {        this.error_code = error_code;    }    public void setReason(String reason) {        this.reason = reason;    }    public void setResult(List result) {        this.result = result;    }    public int getTotal() {        return total;    }    public int getError_code() {        return error_code;    }    public String getReason() {        return reason;    }    public List getResult() {        return result;    }    public static class ResultEntity {        private String famous_name;        private String famous_saying;        public void setFamous_name(String famous_name) {            this.famous_name = famous_name;        }        public void setFamous_saying(String famous_saying) {            this.famous_saying = famous_saying;        }        public String getFamous_name() {            return famous_name;        }        public String getFamous_saying() {            return famous_saying;        }    }}

四、实现过程

首先, 按照官方的说明,我们需要创建一个接口,返回 Call;如下:

@GET("/avatardata/mingrenmingyan/lookup")    Call getFamousResult(@Header("apiKey") String apiKey,                                     @Query("keyword") String keyword,                                     @Query("page") int page,                                     @Query("rows") int rows);

这里我们使用的是Retrofit 提供注解的方式来定义接口的

  • @get后面我们填写需要访问对应的接口地址
  • @Header用来添加Header
  • @Query用来添加查询关键字

现在接口定义好了,我们来** 定义Retrofit 网络接口服务的包装类 **:

package com.woyou.androidsample;import android.content.Context;import retrofit2.GsonConverterFactory;import retrofit2.Retrofit;/** * Retrofit 网络接口服务的包装类 * Created by Xiho on 2016/3/14. */public class RetrofitWrapper {    private static RetrofitWrapper instance;    private Context mContext;    private Retrofit retrofit;    private RetrofitWrapper() {           //1.创建Retrofit对象        retrofit = new Retrofit.Builder().baseUrl(Constant.BASEURL) // 定义访问的主机地址                .addConverterFactory(GsonConverterFactory.create())  //解析方法                .build();    }    /**     * 单例模式     *     * @return     */    public static RetrofitWrapper getInstance() {        if (instance == null) {            synchronized (RetrofitWrapper.class){                if (instance==null){                    instance = new RetrofitWrapper();                }            }        }        return instance;    }    public  T create(final Class service) {        return retrofit.create(service);    }}/**    * Created by Xiho on 2016/3/14.    */public class Constant {        public  static String BASEURL="http://apis.baidu.com"; //服务器地址       public  static String APIKEY="4c4f0c3c49e09d5578ae0ba49fa84a97";}

网络服务的包装类定义好了之后,在定义一个访问的Model(个人编码风格,其实可以更简洁点)。

public class FamousInfoModel {    private static FamousInfoModel famousInfoModel;    private FamousService mFamousService;    /**     * 单例模式     *     * @return     */    public static FamousInfoModel getInstance(Context context) {        if (famousInfoModel == null) {            famousInfoModel = new FamousInfoModel(context);        }        return famousInfoModel;    }    private FamousInfoModel(Context context) {        mFamousService = (FamousService) RetrofitWrapper.getInstance().create(FamousService.class);    }    /**     * 查询名人名言     *     * @param famousInfoReq     * @return     */    public Call queryLookUp(FamousInfoReq famousInfoReq) {        Call infoCall = mFamousService.getFamousResult(famousInfoReq.apiKey, famousInfoReq.keyword, famousInfoReq.page, famousInfoReq.rows);        return infoCall;    }}

五、如何使用

构建好接口以后,可以使用了!

使用分为四步:

  • 创建Retrofit对象
  • 创建访问API的请求
  • 发送请求
  • 处理结果
    主要代码如下:
FamousInfoModel famousInfoModel =FamousInfoModel.getInstance(getApplicationContext());// 获取事件    private void initEvent() {        mSerachBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //创建访问的API请求                Call callFamous= famousInfoModel.queryLookUp(initParams());                //发送请求                callFamous.enqueue(new Callback() {                    @Override                    public void onResponse(Call call, Response response) {                        if(response.isSuccess()){                            FamousInfo result = response.body();                            if(result!=null){                                List entity = result.getResult();                                    mTxtContent.setText("1、"+entity.get(0).getFamous_saying()+"\n---"+entity.get(0).getFamous_name()+"\n 2、"                                            +entity.get(1).getFamous_saying()+"\n---"+entity.get(1).getFamous_name());                            }                        }                    }                    @Override                    public void onFailure(Call call, Throwable t) {                    }                });            }        });    }

最后运行的效果图如下:

QQ截图20160315124740.png QQ截图20160315124757.png

** 搜索的结果我只是显示了其中一部分,只用来使用Retrofit 这个框架,没有很具体去做一些处理啦,后面还会用一些其他的库,还会使用本Demo 来进行测试,所以这次就简单写了下。**

附上源码:AndroidRetrofitSample

六、扩展阅读

** Retrofit:**

  • Retrofit 官方文档:http://square.github.io/retrofit/
  • Retrofit 使用介绍:http://www.cnblogs.com/angeldevil/p/3757335.html
  • Retrofit 离线缓存策略:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0115/3873.html

我的博客:http://blog.csdn.net/u011974987

更多相关文章

  1. Android(安卓)Jetpack之LifeCycle
  2. retrofit2+rxjava的结合使用
  3. android+django交互数据(同时上传图片与文字)
  4. android修改头像以及上传头像
  5. Android入门:用HttpClient模拟HTTP的GET和POST请求
  6. android 网络通信(三):Retrofit 2.0 的使用
  7. Android(安卓)集成微信sdk 实现微信登录
  8. Android(安卓)开发 框架系列 OkHttp使用详解
  9. Android开发中调用Spring CXF整合发布的WebService接口为什么抛

随机推荐

  1. android手机打电话代码分析
  2. Android(安卓)6.0中的新技术有哪些
  3. 黑客瞄准中国Android用户
  4. android service 相关问题汇总
  5. Android系统的开机画面显示过程分析(12)
  6. Android入门篇(一)了解androidstudio开发软
  7. Android上自定义进度条的教学讲解【转】
  8. Android 读取一个已经安装的包的权限
  9. ImageView显示图像控件
  10. Android(安卓)进阶 教你打造 Android(安