Retrofit2 简明教程一.docx

上传人:b****6 文档编号:7056825 上传时间:2023-01-16 格式:DOCX 页数:12 大小:20.88KB
下载 相关 举报
Retrofit2 简明教程一.docx_第1页
第1页 / 共12页
Retrofit2 简明教程一.docx_第2页
第2页 / 共12页
Retrofit2 简明教程一.docx_第3页
第3页 / 共12页
Retrofit2 简明教程一.docx_第4页
第4页 / 共12页
Retrofit2 简明教程一.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

Retrofit2 简明教程一.docx

《Retrofit2 简明教程一.docx》由会员分享,可在线阅读,更多相关《Retrofit2 简明教程一.docx(12页珍藏版)》请在冰豆网上搜索。

Retrofit2 简明教程一.docx

Retrofit2简明教程一

Retrofit2简明教程

(一)

简介

Retrofit是一个Square开发的类型安全的REST安卓客户端请求库。

这个库为网络认证、API请求以及用OkHttp发送网络请求提供了强大的框架。

Retrofit可以利用接口,方法和注解参数来声明式定义一个请求应该如何被创建。

并且可更换或自定义HTTPclient,以及可更换或自定义Converter,返回数据解析方式。

Retrofit可用于Android和Java的一个类型安全(type-safe)的REST客户端,如果你的服务器使用的使RESTAPI,那么你将非常适合使用它。

安装

请选择以下三种方式中一种进行安装,最后如果你正在使用PROGUARD,请添加下方PROGUARD配置。

SOURCE

关于Retrofit源代码以及官方简单例子,请访问

GRADLE(推荐)

如果你正在使用GRADLE在你的项目中的build.gradle添加以下代码到您的配置:

compile'com.squareup.retrofit2:

retrofit:

2.1.0'

MAVEN

如果你正在使用MAVEN在你的项目中的pom.xml添加以下代码到您的配置:

com.squareup.retrofit2

retrofit

2.1.0

PROGUARD

如果你正在使用PROGUARD在你的项目中添加以下代码到您的配置:

-dontwarnretrofit2.**

-keepclassretrofit2.**{*;}

-keepattributesSignature

-keepattributesExceptions

最初的步骤

创建Retrofit实例

在使用Retrofit前,我们需要先创建Retrofit实例,并且做一系列配置,然而Retrofit设计的也是非常好,这些配置都是可插拔的:

Retrofitretrofit=newRetrofit.Builder()

//设置baseUrl,注意baseUrl应该以/结尾。

.baseUrl("http:

//news-

//使用Gson解析器,可以替换其他的解析器

.addConverterFactory(GsonConverterFactory.create())

//设置OKHttpClient,如果不设置会提供一个默认的

.client(newOkHttpClient())

//.client(newUrlConnectionClient())

//.client(newApacheClient())

//.client(newCustomClient())

.build();

更换HTTPclient与Converter

Retrofit背后的HTTPclient,以及序列化机制(JSON/XML协议)等都是可以替换,因此你可以选择自己合适的方案。

Retrofit最早出来的时候,只支持Apache的HTTPclient。

后来增加了URLconnection,以及OkHttp的支持。

如果你想使用其他的HTTPclient,可以通过以下方式了替换,或者更改为自定义的HTTPclient:

//设置OKHttpClient,如果不设置会提供一个默认的OkHttpClient

.client(newOkHttpClient())

//.client(newUrlConnectionClient())

//.client(newApacheClient())

//.client(newCustomClient())

序列化功能也是可替换的。

默认是用的GSON,你当然也可以用Jackson来替换掉。

//使用Gson解析器,可以替换其他的解析器

.addConverterFactory(GsonConverterFactory.create())

//当需要返回原始String数据时

.addConverterFactory(ScalarsConverterFactory.create())

除此之外Retrofit还提供以下几种Converter:

Gson:

com.squareup.retrofit2:

converter-gson

Jackson:

com.squareup.retrofit2:

converter-jackson

Moshi:

com.squareup.retrofit2:

converter-moshi

Protobuf:

com.squareup.retrofit2:

converter-protobuf

Wire:

com.squareup.retrofit2:

converter-wire

SimpleXML:

com.squareup.retrofit2:

converter-simplexml

Scalars(primitives,boxed,andString):

com.squareup.retrofit2:

converter-scalars

基本使用

我们将看一下如何用Retrofit与服务器交互,通过它你将学会如何运用Retrofit于日常开发。

Retrofit使用接口,方法和参数,使用注解表明了请求将如何处理,每一种方法都必须有一个HTTP标注提供请求的方法和相对URL,有五种内置注解:

GET,POST,PUT,DELETE,和HEAD,在注解中指定URL。

请选择以下方式中合适的请求方式来处理您的请求。

GET

在这里我们最开始第一个GET请求使用的是知乎日报的api,为了更好使用Retrofit其他请求方式而又没有比较好的公开api,我自行编写了配合使用Retrofit的测试服务端,放置在外网以便大家测试使用。

普通GET

基于上面的最初的步骤,接下来我们需要定义一个接口,并且使用注解(@GET)表明一次GET请求:

publicinterfaceZhihuService{

//获取启动页大图

@GET("start-image/1080*1776")

CallgetStartImage();

}

这是一个普通的GET请求,接着我们来看如何利用Retrofit创建服务接口,并且设置参数:

ZhihuServicemessageService=retrofit.create(ZhihuService.class);

CallstartImage=messageService.getStartImage();

最后,使用startImage.enqueue进行异步请求,并且获取了我们期待的数据(实体对象):

startImage.enqueue(newCallback(){

@Override

publicvoidonResponse(Callcall,Responseresponse){

if(response.isSuccessful()){

Log.d(TAG,response.body().toString());

resultTextView.setText(""+response.body().toString());

}

}

@Override

publicvoidonFailure(Callcall,Throwablet){

resultTextView.setText(""+"error:

"+t.getMessage());

}

});

如果你想使用call.execute()进行同步请求,需要注意的是不要放在UI线程:

try{

Responseresponse=call.execute();//同步

Log.d(TAG,"response:

"+response.body().toString());

}catch(IOExceptione){

e.printStackTrace();

}

因为一次call.execute()的request只能执行一次,否则你将会得到如下错误:

java.lang.IllegalStateException:

Alreadyexecuted

如果你想取消本次请求可以使用startImage.cancel()或者是复制一次request,再次请求:

startImage.cancel();//取消

CallcloneRequsest=startImage.clone();//复制

是不是感觉特别简单,使用时候只需调用接口,这一切都简化了我们的操作。

动态参数(GET)

我们需要先定义一个接口,并且使用注解(@Query)或者是@QueryMap表明动态参数请求如何处理:

相应的URL是这样:

http:

//baseurl/app/test/sayHello?

username=fuchenxuan&age=110

@GET("test/sayHello")

CallsayHello(@Query("username")Stringusername,@Query("age")Stringage);

接着我们忽略接口的创建,直接使用Retrofit与服务器交互,值得注意的是我们此次返回的数据是String,而不是一个自定义的实体类对象。

所以我们需要更换Converter,否则你将会遇到不必要的麻烦(而我觉得Retrofit应该提供一个默认Stirng的实现):

//当需要返回原始String数据时

.addConverterFactory(ScalarsConverterFactory.create())

接着我们就得到了我们期待的数据:

CalldoubanCall=myTestApiService.sayHello("fuchenxuan","110");

doubanCall.enqueue(newCallback(){

@Override

publicvoidonResponse(Callcall,Responseresponse){

if(response.isSuccessful()){

Log.d(TAG,response.body().toString());

resultTextView.setText(""+response.body().toString());

}

}

@Override

publicvoidonFailure(Callcall,Throwablet){

}

});

RESTful方式(动态PATH)

GET动态PATH就是优雅的RESTfulapi方式,

相应的URL是这样:

http:

//news-

@GET("start-image/{size}")

CallgetStartImageByPath(@Path("size")Stringsize);

POST

form-data(表单数据)

form-data就是如表单K-V参数形式

这里其实就跟GET的动态参数是一致的只是替换了@POST注解

publicinterfaceMyTestApiService{

@POST("test/sayHello")

CallpostSayHello(@Query("username")Stringusername,@Query("age")Stringage);

}

JSON参数(raw)

当服务器需要你POST参数以json打包数据格式请求时,然而这种参数方式RESTfulapi也是非常常见的,我们需要使用@Body注解:

@POST("test/sayHi")

//@Headers("Accept-Encoding:

application/json")

//使用@Headers可添加header

CallpostSayHi(@BodyUserBeanuserBean);

上面我们还示例了如何使用@Headers@Headers("Accept-Encoding:

application/json")添加头部信息,或者我们有需求需要使用@Header实现动态头部信息:

@POST("test/sayHi")

@Headers("Accept-Encoding:

application/json")

//也可以使用@Header可添加header

CallpostSayHi(@BodyUserBeanuserBean,@Header("city")Stringcity);

RESTful方式(动态PATH)

前面也说了retrofit非常适用于RESTfulurl的格式,这里因为知乎的就是RESTfulapi,我们直接使用和GET动态URL一样的注解(@PATH)来表明请求处理:

相应的URL是这样:

http:

//news-

@POST("start-image/{size}")

CallgetStartImageByPath(@Path("size")Stringsize);

文件上传

在我们开发当中肯定必不可少图片上传了,我们使用表单上传文件时,必须让表单的enctyped等于multipart/form-data。

文件上传我们需要使用@MultiPart和@Part,MultiPart意思就是允许多个@Part多部分上传。

@Multipart

@POST("test/upload")

Callupload(@Part("file\";filename=\"launcher_icon.png")RequestBodyfile);

值得注意的是我们需要在@Part指定file和filename的值,避免一些不必要的麻烦。

相应的我们在使用retrofit的时候,首先先获取到文件,并且创建RequestBody实例,然后调用接口请求,相应代码块如下:

Filefile=newFile(getExternalFilesDir(null),"launcher_icon.png");

RequestBodyfileBody=RequestBody.create(MediaType.parse("image/png"),file);

CalldoubanCall=myTestApiService.upload(fileBody);

doubanCall.enqueue(newCallback(){

@Override

publicvoidonResponse(Callcall,Responseresponse){

if(response.isSuccessful()){

Log.d(TAG,response.body().toString());

resultTextView.setText(""+response.body().toString());

}

}

@Override

publicvoidonFailure(Callcall,Throwablet){

//Log.d(TAG,response.body().toString());

resultTextView.setText(""+"error:

"+t.getMessage());

}

});

大文件下载

文件下载我们需要使用@Url和@Streaming,@Url动态Url正好非常适合我们的场景,而使用@Streaming注解可以让我们下载非常大的文件时,避免Retrofit将整个文件读进内存,否则可能造成OOM现象。

声明接口如下:

@Streaming

@GET

CalldownloadFileByDynamicUrlAsync(@UrlStringdownloadUrl);

需要注意的是我们需要使用Retrofitcall.execute同步获取ResponseBody,那么我们就需要放进一个单独的工作线程中:

newAsyncTask(){

@Override

protectedVoiddoInBackground(Void...voids){

Callcall=myTestApiService.downloadFileByDynamicUrlAsync(API_BASE_URL.concat("/res/atom-amd64.deb"));

try{

Responseresponse=call.execute();

booleanwrittenToDisk=writeResponseBodyToDisk(response.body());

Log.d(TAG,"下载文件"+writtenToDisk);

}catch(IOExceptione){

e.printStackTrace();

}

returnnull;

}

@Override

protectedvoidonPreExecute(){

super.onPreExecute();

}

}.execute();

最后我们需要将文件写入磁盘根目录中:

//写入到磁盘根目录

privatebooleanwriteResponseBodyToDisk(ResponseBodybody){

try{

FilefutureStudioIconFile=newFile(Environment.getExternalStorageDirectory()+File.separator+"atom.deb");

InputStreaminputStream=null;

OutputStreamoutputStream=null;

try{

byte[]fileReader=newbyte[4096];

finallongfileSize=body.contentLength();

longfileSizeDownloaded=0;

inputStream=body.byteStream();

outputStream=newFileOutputStream(futureStudioIconFile);

while(true){

intread=inputStream.read(fileReader);

if(read==-1){

break;

}

outputStream.write(fileReader,0,read);

fileSizeDownloaded+=read;

Log.d(TAG,"filedownload:

"+fileSizeDownloaded+"of"+fileSize);

finallongfinalFileSizeDownloaded=fileSizeDownloaded;

runOnUiThread(newRunnable(){

@Oride

publicvoidrun(){

resultTextView.setText("filedownload:

"+finalFileSizeDownloaded+"of"+fileSize);

}

});

}

outputStream.flush();

returntrue;

}catch(IOExceptione){

returnfalse;

}finally{

if(inputStream!

=null){

inputStream.close();

}

if(outputStream!

=null){

outputStream.close();

}

}

}catch(IOExceptione){

returnfalse;

}

}

这样我们就可以非常高效的下载大文件了,最后友情提醒(如果是6.0以上另外再申请权限):

name="android.permission.INTERNET"/>

name="android.permission.WRITE_EXTERNAL_STORAGE"/>

注解

尽管文章前面已经把Retrofit2注解基本了解完了,但是有必要多了解一些其他的注解,或许您正好有这样的场景需求,他们分别可作用于方法和参数:

@Headers:

用于在方法添加请求头:

@POST("test/sayHi")

@Headers("Accept-Encoding:

application/json")

CallpostSayHi(@BodyUserBeanuserBean,@Header("city")Stringcity);

@Streaming

如果您正在下载一个大文件,Retrofit2将尝试将整个文件移动到内存中。

为了避免这种,我们必须向请求声明中添加一个特殊的注解@Streaming

@Streaming

@GET

CalldownloadFileByDynamicUrlAsync(@UrlStringfileUrl);

@Header:

用于在方法参数里动态添加请求头:

C

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1