框架学习| Retrofit2.x(一)

开新坑辣!一直觉得自己框架了解的特别少,大多只知其名而不知实现原理,然而几乎每次面试都会被问及框架。所以很有必要总结一些常用的框架,希望自己能坚持把这个『框架学习』系列的新坑填的厚实一点!

先从网络框架中大名鼎鼎的Retrofit开始吧,本篇先对Retrofit有个了解,目录如下:

  • 概述
  • 使用方式

1.概述

a.Retrofit是Square公司推出的一个基于RESTful风格的HTTP网络框架。

相关链接地址:

b.与OkHttp的关系:

是对OkHttp网络请求框架的二次封装,本质仍是OkHttp。即网络请求的工作本质上是由OkHttp完成,而Retrofit仅负责网络请求接口的封装。流程如图:

  • App应用程序通过Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数、Header、Url等信息,之后由OkHttp完成后续的请求操作。
  • 在服务端返回数据之后,OkHttp将原始的结果交给Retrofit,Retrofit会根据用户的需求对结果进行解析。
  • 通过使用大量的设计模式进行功能模块的解耦,使得上面的过程进行得更加简单和流畅。

c.其他网络框架简介:

  • AndroidAsynHttp:基于HttpClient,已经停止维护,Android5.0不再使用HttpClient。
  • Volley:基于HttpUrlConnection,由谷歌官方推出,适合轻量级网络交互,如数据传输量小的场景,而不适合大文件传输。

相比于上述两种网络框架,Retrofit具有的优点

  • 遵循Restful API设计风格,简洁易用
  • 支持同步&异步网络请求
  • 支持多种数据的解析&序列化格式(Gson、 Json、XML、 Protobuf)
  • 支持对RxJava支持
  • 注解化配置高度解耦、采用大量设计模式简化使用

2.使用方式

大致分成八个步骤:

step1:添加Retrofit库、OkHttp库、数据解析器集成库的依赖,并注册网络权限

在app文件包下的build.gradle中添加依赖,这里用的是JSON数据解析器:

compile 'com.squareup.retrofit2:retrofit:2.4.0'
compile 'com.squareup.okhttp3:okhttp:3.10.0'
compile 'com.squareup.retrofit2:converter-gson:2.4.0'

在AndroidManifest.xml中注册权限:

<uses-permission android:name="android.permission.INTERNET"/>

step2:创建接收服务器返回数据的类

请求后服务器会返回数据,需要根据返回数据的格式和解析方式(Json、XML等)来定义实体类Model。

假设有返回数据格式为如下JSON,其中,如果用户名和密码匹配成功,则code值为1,反之为0:

{
  "code":1,
  "data":{
     "id":10001,
     "username":"Tom",
     "email":"888888888@qq.com",
     "tel":"18088888888"
  },
  "message":"success"
}

则对应的实体类UserInfoModel:

public class UserInfoModel {

    public int code;
    public UserInfo data;
    public String message;
    
    public static class UserInfo{
    
        public int id;
        public String username;
        public String email;
        public String tel;
    }
}

step3:创建用于描述网络请求的接口

定义一个网络请求的接口,接口函数里要定义URL路径请求参数返回类型。其中,需要使用注解来描述请求类型和请求参数。

public interface Interface {
  
    @GET("URL")
    Call<Model>  getCall(@Query("xxx") String xxx);
   
    // 用@GET("URL")声明了URL路径
    // 用getCall()接收网络请求数据,并用注解@Query("xxx") 声明了请求参数
    // 该方法会返回一个Retrofit的Call对象,这里声明了这个对象处理的数据类型为自定义Model
}

在上例中,对应的UserMgrService接口如下,当发送请求参数为Tom和123456时,请求将发送给的URL为『login?username=Tom&pwd=123456』,并会返回之前定义的GSON数据:

public interface UserMgrService{
    
    @GET("login")
    Call<UserInfoModel> login(@Query("username") String username,@Query("pwd") String pwd);
}

常用的注解含义如图:

这里可以发现,@GET和@Query搭配使用,@POST和@Field搭配使用。


step4:创建Retrofit对象并设置数据解析器

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("URL") //设置网络请求的Url地址,注意以要以斜线(代表根目录)结尾
                .addConverterFactory(GsonConverterFactory.create()) //设置数据解析器,这里表示用的是JSON解析返回值
                .build();

常用的数据解析器如图:


step5:生成接口对象

由于是interface不是class,无法直接调用内部方法,需要利用已创建的Retrofit对象去生成代理的接口对象。

UserMgrService service=retrofit.create(UserMgrService.class);

step6:调用接口方法返回Call对象

调用接口对象的方法,返回一个可以执行网络访问的网络工作对象。

Call<UserInfoModel> call=service.login("Tom","123456");

step7:发送网络请求(异步 / 同步)

a.同步:调用Call对象execute(),返回结果是响应体。

//开线程进行网络请求
new Thread(new Runable()){
    @Override
    pubblic void run(){
        Response<UserInfoModel> response=null;
        try{
           response=call.execute();
        }catch{
           e.printStackTrace();
        }
        //处理服务器返回的数据
    }
}.start();

b.异步:调用Call对象enqueue(),参数是一个回调。

//异步时,框架中已经封装好数据转换、线程切换的操作,无需手动开线程
call.enqueue(new CallBack<UserInfoModel>(){
    @Override
    public void onResponse(Call<UserInfoModel> call,Response<UserInfoModel> response){
        //处理服务器返回的数据
    }
    @Override
    public void onFailure(Call<UserInfoModel> call,Throwable t){
    }
});

step8: 处理服务器返回的数据

现在可以去打印出返回结果:

Log.i("response","code:"+response.body().code);//结果为"code:1"

下面给出官方给的simple demo,便于更好的理解Retrofit的使用步骤:

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

  public static void main(String... args) throws IOException {
    // step4:Create a very simple REST adapter which points the GitHub API.
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(API_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

    // step5:Create an instance of our GitHub API interface.
    GitHub github = retrofit.create(GitHub.class);

    // step6:Create a call instance for looking up Retrofit contributors.
    Call<List<Contributor>> call = github.contributors("square", "retrofit");

    // step7:Fetch and print a list of the contributors to the library.
    List<Contributor> contributors = call.execute().body();
    
    //step8:
    for (Contributor contributor : contributors) {
      System.out.println(contributor.login + " (" + contributor.contributions + ")");
    } 
  }

实例这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)


以上,可以看到,Retrofit可根据不同的接口定义,灵活地生成对应的网络工作对象,然后利用这个对象去访问网络。它就像一个工厂,只提供产品,本身不处理网络请求,而是让产品去处理网络请求。

图片来源从架构角度看Retrofit的作用、原理和启示

下一篇将进行Retrofit的源码分析~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,458评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,030评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,879评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,278评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,296评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,019评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,633评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,541评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,068评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,181评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,318评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,991评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,670评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,183评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,302评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,655评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,327评论 2 358

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,227评论 25 707
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,982评论 3 119
  • 那天带闺女去杜陵•秦砖汉瓦博物馆玩,正赶上一队团体游客也在里面参观,看样子是一个楼盘组织的活动。博物馆里除了这队人...
    Double_Sun阅读 554评论 0 1
  • 一条母亲河吞噬了很多的生命,我就是曾经被人救下的活口。 时隔二十多年,今天回娘家碰到了我的恩人...
    琴弦封存阅读 240评论 0 0