android responsebodytrofit onresponse 判断哪个请求

Android 初探Retrofit2.0.1(最新版)
看见这段开头,你应该听过Retrofit的大名但是没有真正的运用过,或者用过Retrofit1.9但是没有跟上更新的进度。无论什么原因,你都该好好了解下这篇博客。1.9和2.0.1版本差别很大。
看见这段开头,你应该听过Retrofit的大名但是没有真正的运用过,或者用过Retrofit1.9但是没有跟上更新的进度。无论什么原因,你都该好好了解下这篇博客。1.9和2.0.1版本差别很大。网上相关的教程很少,又因为是初探,所以本篇博客会用一个Demo说明Retrofit2.0.1的用法,
Retrofit GitHub地址:
Retrofit 项目主页:
用一个Demo初探Retrofit
个人强烈建议先去浏览一遍上面的Retrofit 项目主页,会有助你了解Retrofit的基本用法和特性。
Demo结构概览
采用API Store里的天气接口,完整接口(带参数)地址:
MainActivity,没做封装,请求相关的逻辑调用都写在这里
bean目录,GSON解析数据所用到的类
service目录,定义请求相关参数及返回数据格式
使用Retrofit获取String类型的数据
compile ‘com.squareup.retrofit2:retrofit:2.0.1’
从service目录开始
首先需要定义一个类名为WeatherInfoService的interface
public interface WeatherInfoService {
@GET("/weather/index?format=2&cityname=北京&key=b952ad7acbcc9bf274e39c45")
Call&ResponseBody& getString();
这里定义了一个名为getString()的抽象方法,由于这里没有指定返回类型,所以Call里面的泛型指定为ResponseBody。因为现在获取的是String类型的数据,所以暂时用不上Bean目录,直接进图MainActivity
MainActivity
private static final String BASE_URL = "/";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
tv = (TextView) findViewById(R.id.tv);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).build();
WeatherInfoService weatherInfoService = retrofit.create(WeatherInfoService.class);
Call&ResponseBody& call = weatherInfoService.getString();
call.enqueue(new Callback&ResponseBody&() {
public void onResponse(Call&ResponseBody& call, Response&ResponseBody& response) {
tv.setText(response.body().string());
} catch (IOException e) {
e.printStackTrace();
public void onFailure(Call&ResponseBody& call, Throwable t) {
tv.setText(t.getMessage());
乍一看有点蒙,没关系我们慢慢来。
1. 首先我们创建了一个retrofit对象,这里需要注意下BASE_URL这个参数,如果@GET方法里的URl是完整的,则不拼接参数,否则拼接URL。
2. 接着我们将WeatherInfoService当做参数传递给retrofit的create()方法,返回值是WeatherInfoService的一个对象。这部分几乎是固定的,如果想简单封装可以在这部分做点手脚。
3. 然后调用WeatherInfoService对象的getString()方法,得到一个call
4. call有两种执行方式,一种是像上文中调用call.enqueue异步执行。既然有异步,那肯定得有同步。同步方法:Response&WeatherInfo& res = call.execute(); WeatherInfo info =
res.body(); 4.0后不能在主线程访问网络,所以同步需要新开线程。有兴趣自己测试下,不在本文之列。
至此我们已经有了一个使用Retrofit获取String数据的方法,但是通常情况下我们的服务器会返回JSON/XML格式的数据,以JSON居多。别急,Retrofit已经为我们考虑好了这一点。
使用Retrofit获取JSON类型的数据
compile ‘com.squareup.retrofit2:converter-gson:2.0.0-beta4’
这里使用GSON解析数据,当然你也可以换做其他的。支持列表如下
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 Simple XML:
com.squareup.retrofit2:converter-simplexml
还是那个service
public interface WeatherInfoService {
@GET("/weather/index?format=2&cityname=北京&key=b952ad7acbcc9bf274e39c45")
Call&ResponseBody& getString();
@GET("/weather/index?format=2&cityname=北京&key=b952ad7acbcc9bf274e39c45")
Call&WeatherInfo& getWeatherInfo();
同样的WeatherInfoService,方法名改为getWeatherInfo,指定返回Call中的泛型为WeatherInfo,下面简单展示下WeatherInfo这个Bean
等了好久的JavaBean
由于Bean有点多,而且都是GSON解析时对应的数据,都是getter/setter故这里只展示两个作为参考。
public class WeatherInfo {
private String error_
public class Result {
private List&Future&
对比 返回的数据,相信应该很容易理解,不再赘述。
还是那个MainActivity
btn2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final Gson gson = new GsonBuilder().create()
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
WeatherInfoService weatherInfoService = retrofit.create(WeatherInfoService.class)
Call&WeatherInfo& call= weatherInfoService.getWeatherInfo()
call.enqueue(new Callback&WeatherInfo&() {
public void onResponse(Call&WeatherInfo& call, Response&WeatherInfo& response) {
WeatherInfo info = response.body()
Log.i(TAG,gson.toJson(info))
tv.setText(gson.toJson(info))
public void onFailure(Call&WeatherInfo& call, Throwable t) {
tv.setText("error"+t.getMessage())
细心的同学会注意到创建Retrofit对象的时候多了一行代码.addConverterFactory(GsonConverterFactory.create(gson)) 和想象中一样添加了GSON解析器。不过是两行代码的事情,居然就可以直接返回GSON解析后的对象了。Retrofit确实方便,而且可拓展性杠杠的。
请求带参数
只需修改WeatherInfoService中的方法,完整的WeatherInfoService代码如下
package com.dyk.retrofit2.
import com.dyk.retrofit2.bean.WeatherI
import okhttp3.ResponseB
import retrofit2.C
import retrofit2.http.GET;
import retrofit2.http.Q
* Created by dyk on .
public interface WeatherInfoService {
@GET("/weather/index?format=2&cityname=北京&key=b952ad7acbcc9bf274e39c45")
Call&ResponseBody& getString();
@GET("/weather/index?/")
Call&WeatherInfo& getWeatherInfo(@Query("format") String format, @Query("cityname") String cityname, @Query("key") String key);
@GET("/weather/index?format=2&cityname=北京&key=b952ad7acbcc9bf274e39c45")
Call&WeatherInfo& getWeatherInfo();
MainActivity中调用的时候自然要传入相应的参数,MainActivity全部代码如下
package com.dyk.retrofit2;
import android.app.A
import android.os.B
import android.util.L
import android.view.V
import android.widget.B
import android.widget.TextV
import com.dyk.retrofit2.bean.WeatherI
import com.dyk.retrofit2.service.WeatherInfoS
import com.google.gson.G
import com.google.gson.GsonB
import java.io.IOE
import okhttp3.ResponseB
import retrofit2.C
import retrofit2.C
import retrofit2.R
import retrofit2.R
import retrofit2.converter.gson.GsonConverterF
public class MainActivity extends Activity {
private static final String TAG = "retrofit2";
private static final String BASE_URL = "/";
private static final String FORMAT = "2";
private static final String CITYNAME = "北京";
private static final String KEY = "b952ad7acbcc9bf274e39c45";
private Button btn2;
private TextV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
tv = (TextView) findViewById(R.id.tv);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).build();
WeatherInfoService weatherInfoService = retrofit.create(WeatherInfoService.class);
Call&ResponseBody& call = weatherInfoService.getString();
call.enqueue(new Callback&ResponseBody&() {
public void onResponse(Call&ResponseBody& call, Response&ResponseBody& response) {
tv.setText(response.body().string());
} catch (IOException e) {
e.printStackTrace();
public void onFailure(Call&ResponseBody& call, Throwable t) {
tv.setText(t.getMessage());
btn2 = (Button) findViewById(R.id.btn2);
btn2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final Gson gson = new GsonBuilder().create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
WeatherInfoService weatherInfoService = retrofit.create(WeatherInfoService.class);
Call&WeatherInfo& call= weatherInfoService.getWeatherInfo(FORMAT, CITYNAME, KEY);
call.enqueue(new Callback&WeatherInfo&() {
public void onResponse(Call&WeatherInfo& call, Response&WeatherInfo& response) {
WeatherInfo info = response.body();
Log.i(TAG,gson.toJson(info));
tv.setText(gson.toJson(info));
public void onFailure(Call&WeatherInfo& call, Throwable t) {
tv.setText("error"+t.getMessage());
很早就有闻Retrofit大名,终究没能一见。周末没事找Retrofit练练手,顺便学点新东西,结果网上极少有2.0.1版本(目前最新版)的教程。写完Demo后分享给大家,由于第一次接触Retrofit2.0.1,深度可能不是很够,但一定是最新的。后续还会继续深入了解Retrofit,希望大家能够关注。
版权声明:本文内容由互联网用户自发贡献,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至: 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
用云栖社区APP,舒服~
【云栖快讯】红轴机械键盘、无线鼠标等753个大奖,先到先得,云栖社区首届博主招募大赛9月21日-11月20日限时开启,为你再添一个高端技术交流场所&&
@GET("{path}")
Call getRequest(@Path("path") String path, @QueryMap Map parameter);
如果把返回实体对象改为String
请求成功 但是它不执行回调,郁闷!
@GET("{path}")
Call getRequest(@Path("path") String path, @QueryMap Map parameter);
如果是放的 实体对象 则请求成功并且成功执行回调
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...
RDS是一种稳定可靠、可弹性伸缩的在线数据库服务。支持MySQL、SQL Server、PostgreSQL、高...
MaxCompute75折抢购
Loading...【Android实战】----基于Retrofit实现多图片/文件、图文上传
时间: 16:47:43
&&&& 阅读:181
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&一、再次膜拜下RetrofitRetrofit无论从性能还是使用方便性上都很屌!!!,本文不去介绍其运作原理(虽然很想搞明白),后面会出专题文章解析Retrofit的内部原理;本文只是从使用上解析Retrofit实现多图片/文件、图文上传的功能。二、概念介绍1)注解@Multipart从字面上理解就是与多媒体文件相关的,没错,图片、文件等的上传都要用到该注解,其中每个部分需要使用@Part来注解。。看其注释/**
* Denotes that the request body is multi-part. Parts should be declared as parameters and
* annotated with {@link Part @Part}.
*/2)注解@PartMap当然可以理解为使用@PartMap注释,传递多个Part,以实现多文件上传。注释/**
* Denotes name and value parts of a multi-part request.
* Values of the map on which this annotation exists will be processed in one of two ways:
* &li&If the type is {@link okhttp3.RequestBody RequestBody} the value will be used
* directly with its content type.&/li&
* &li&Other object types will be converted to an appropriate representation by using
* {@linkplain Converter a converter}.&/li&
* &pre&&code&
* @Multipart
* @POST(&/upload&)
* Call&ResponseBody& upload(
@Part(&file&) RequestBody file,
@PartMap Map&String, RequestBody& params);
* &/code&&/pre&
* A {@code null} value for the map, as a key, or as a value is not allowed.
* @see Multipart
* @see Part
*/3)RequestBody从上面注释中就可以看到参数类型是RequestBody,其就是请求体。文件上传就需要参数为RequestBody。官方使用说明如下Multipart parts use one of Retrofit‘s converters or they can implement RequestBody to handle their own serialization.四、基本实现了解了以上概念,下面就一一实现1)接口定义public interface IHttpService {
@Multipart
@POST(&nocheck/file/agree.do&)
Call&BaseBean& upLoadAgree(@PartMap Map&String, RequestBody&params);
}BaseBean是根据服务端返回数据进行定义的,这个使用时可以根据自有Server定义。2)Retrofit实现/**
* Created by DELL on .
* 上传文件用(包含图片)
public class RetrofitHttpUpLoad {
* 超时时间60s
private static final long DEFAULT_TIMEOUT = 60;
private volatile static RetrofitHttpUpLoad mI
public Retrofit mR
public IHttpService mHttpS
private Map&String, RequestBody& params = new HashMap&String, RequestBody&();
private RetrofitHttpUpLoad() {
mRetrofit = new Retrofit.Builder()
.baseUrl(UrlConfig.ROOT_URL)
.client(genericClient())
.addConverterFactory(GsonConverterFactory.create())
mHttpService = mRetrofit.create(IHttpService.class);
public static RetrofitHttpUpLoad getInstance() {
if (mInstance == null) {
synchronized (RetrofitHttpUpLoad.class) {
if (mInstance == null)
mInstance = new RetrofitHttpUpLoad();
* 添加统一超时时间,http日志打印
public static OkHttpClient genericClient() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(logging)
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
return httpC
* 将call加入队列并实现回调
* @param call
调入的call
* @param retrofitCallBack 回调
* @param method
调用方法标志,回调用
* @param &T&
public static &T& void addToEnqueue(Call&T& call, final RetrofitCallBack retrofitCallBack, final int method) {
final Context context = MyApplication.getContext();
call.enqueue(new Callback&T&() {
public void onResponse(Call&T& call, Response&T& response) {
LogUtil.d(&retrofit back code ====& + response.code());
if (null != response.body()) {
if (response.code() == 200) {
LogUtil.d(&retrofit back body ====& + new Gson().toJson(response.body()));
retrofitCallBack.onResponse(response, method);
LogUtil.d(&toEnqueue, onResponse Fail:& + response.code());
ToastUtil.makeShortText(context, &网络连接错误& + response.code());
retrofitCallBack.onFailure(response, method);
LogUtil.d(&toEnqueue, onResponse Fail m:& + response.message());
ToastUtil.makeShortText(context, &网络连接错误& + response.message());
retrofitCallBack.onFailure(response, method);
public void onFailure(Call&T& call, Throwable t) {
LogUtil.d(&toEnqueue, onResponse Fail unKnown:& + t.getMessage());
t.printStackTrace();
ToastUtil.makeShortText(context, &网络连接错误& + t.getMessage());
retrofitCallBack.onFailure(null, method);
* 添加参数
* 根据传进来的Object对象来判断是String还是File类型的参数
public RetrofitHttpUpLoad addParameter(String key, Object o) {
if (o instanceof String) {
RequestBody body = RequestBody.create(MediaType.parse(&text/charset=UTF-8&), (String) o);
params.put(key, body);
} else if (o instanceof File) {
RequestBody body = RequestBody.create(MediaType.parse(&multipart/form-charset=UTF-8&), (File) o);
params.put(key + &\&; filename=\&& + ((File) o).getName() + &&, body);
* 构建RequestBody
public Map&String, RequestBody& bulider() {
}其中定义了Retrofit实例、还用拦截器定义了统一的超时时间和日志打印;将call加入队列并实现回调。最重要的就是添加参数: /**
* 添加参数
* 根据传进来的Object对象来判断是String还是File类型的参数
public RetrofitHttpUpLoad addParameter(String key, Object o) {
if (o instanceof String) {
RequestBody body = RequestBody.create(MediaType.parse(&text/charset=UTF-8&), (String) o);
params.put(key, body);
} else if (o instanceof File) {
RequestBody body = RequestBody.create(MediaType.parse(&multipart/form-charset=UTF-8&), (File) o);
params.put(key + &\&; filename=\&& + ((File) o).getName() + &&, body);
}这里就是根据传入的参数,返回不同的RequestBody。3)使用private void upLoadAgree() {
showWaitDialog();
RetrofitHttpUpLoad retrofitHttpUpLoad = RetrofitHttpUpLoad.getInstance();
if (!StringUtil.isEmpty(pathImage[0])){
retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter(&pic1&,new File(pathImage[0]));
if (!StringUtil.isEmpty(pathImage[1])){
retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter(&pic2&, new File(pathImage[1]));
if (!StringUtil.isEmpty(pathImage[2])){
retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter(&zip&, new File(pathImage[2]));
Map&String, RequestBody& params = retrofitHttpUpLoad
.addParameter(&status&, &4&)
.addParameter(&pickupId&, tv_orderquality_pid.getText().toString())
.addParameter(&cause&, reason)
.addParameter(&connectname&, et_orderquality_lxrname.getText().toString())
.addParameter(&connectphone&, et_orderquality_lxrphone.getText().toString())
.addParameter(&details&, et_orderquality_xqms.getText().toString())
.bulider();
RetrofitHttpUpLoad.addToEnqueue(RetrofitHttpUpLoad.getInstance().mHttpService.upLoadAgree(params),
this, HttpStaticApi.HTTP_UPLOADAGREE);
}需要注意的是要对图片及文件路径进行判空操作,负责会报异常W/System.err: java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)??标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&国之画&&&& &&&&chrome插件&&
版权所有 京ICP备号-2
迷上了代码!Retrofit是一套RESTful架构的Android(Java)客户端实现,基于注解,提供JSON to POJO(Plain Ordinary Java Object,简单Java对象),POJO to JSON,网络请求(POST,GET,PUT,DELETE等)封装。
软件首页http://square.github.io/retrofit/
github地址/square/retrofit
官方文档非常清晰,Retrofit2对Retrofit做了很大改进,针对改进做一下分析和使用说明
底层okhttp不同
Retrofit 默认使用okhttp
Retrofit2 默认使用okhttp3
Service接口定义方式不同
在Retrofit2之前如果定义一个同步的函数,应该这样定义:
public interface GitHubService {
@POST(&/list&)
Repo loadRepo();
}异步函数定义
public interface GitHubService {
@POST(&/list&)
void loadRepo(Callback&Repo& cb);
}Retrofit2 同步异步方法定义一个接口就可以了
mport retrofit.C
public interface GitHubService {
@POST(&/list&)
Call&Repo& loadRepo();
如果要调用同步请求,只需调用execute;而发起一个异步请求则是调用enqueue。
Retrofit2 可以取消请求方法
Retrofit2请求使用Call,Call有cancel方法可以取消请求
只需调用call.cancel()就可以取消请求。
Converter现在从Retrofit2中删除,需要根据自己的需要引入Converter
这里是Square提供的官方Converter modules列表。选择一个最满足你需求的。
Gson: com.squareup.retrofit:converter-gson
Jackson: com.squareup.retrofit:converter-jackson
Moshi: com.squareup.retrofit:converter-moshi
Protobuf: com.squareup.retrofit:converter-protobuf
Wire: com.squareup.retrofit:converter-wire
Simple XML: com.squareup.retrofit:converter-simplexml
Retrofit2 新的URL定义方式
Retrofit接口请求URL要求用/开头,必须设置baseUrl,接口请求URL不能是完整路径。可以使用Endpoint切换服务器路径
于 Retrofit2中新的URL定义方式,建议
- Base URL: 总是以 /结尾
- @Url: 不要以 / 开头
Retrofit2中没有Endpoint这个类,@Url中可以包含完整的路径,包含完整路径baseUrl会被忽略
public interface APIService {
@POST(&/test)
Call&Users& loadUsers();
Retrofit2 需要OkHttp的支持
OkHttp在Retrofit里是可选的。如果你想让Retrofit 使用OkHttp 作为HTTP 连接接口,需要手动包含okhttp 依赖。
但是在Retrofit2中,OkHttp 是必须的,并且自动设置为了依赖。
Retrofit2缺少INTERNET权限会导致SecurityException异常
在Retrofit 中,如果忘记在AndroidManifest.xml文件中添加INTERNET权限。异步请求会直接进入failure回调方法,得到PERMISSION DENIED 错误消息。没有任何异常被抛出。但是在Retrofit2中,当调用call.enqueue或者call.execute,将立即抛出SecurityException,如果不使用try-catch会导致崩溃。
即使response存在问题onResponse依然被调用
在Retrofit中,如果获取的 response 不能背解析成定义好的对象,则会调用failure。但是在Retrofit2中,不管 response 是否能被解析。onResponse总是会被调用。但是在结果不能被解析的情况下,response.body()会返回null。只有抛出异常才会调用onFailure
拦截器不同
在Retrofit中,可以使用RequestInterceptor来拦截一个请求,但是它已经从Retrofit2 移除了,因为HTTP连接层已经完全转为OkHttp。
Retrofit2使用okhttp的拦截器
Retrofit的创建
Retrofit是个final类,不能再定义子类,Retrofit没有public构造方法,只能使用构建的者方式Retrofit.Builder构建。
etrofit.Builder可以指定url根地址、采用的网络客户端、回调线程池、请求拦截器、返回数据格式器和错误处理。
通常必须调用baseUrl,addConverterFactory这两个方法。
构建器默认使用OkHttpClient作为网络请求工具,addCallAdapterFactory用来构建请求实例,callbackExecutor指定回调方法线程池,根据不同平台构建不同,Android构建的是defaultCallbackExecutor,默认在主线程中。validateEagerly默认为false,表示执行的时候再去解析注解。如果设置为true,那么create实例之后,就会先解析接口所有方法。
if (baseUrl == null) {
throw new IllegalStateException(&Base URL required.&);
}&pre name=&code& class=&java&& public &T& T create(final Class&T& service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class&?&[] { service },
请求实例的创建
调用Retrofit的create方法,创建了执行请求对象的代理,代理方法的执行中,对于Object方法和默认方法,直接执行,其它方法解析后执行。使用代理加注解,是Retrofit的核心思想。
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class&?&[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, Object... args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall&&(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
接口的解析过程
loadServiceMethod中首先从缓存中找解析的方法,找到直接返回,否则解析方法,然后放入缓存中。解析过的接口保存在了serviceMethodCache中,防止重复解析,提高效率。解析方法使用ServiceMethod.Builder构建解析器。
build过程中,首先创建callAdapter,
解析中有一系列规则,发现异常会抛出异常
方法返回的参数不能是泛型,不能是基本数据类型,不能是void。
注解不能为空
创建完callAdapter继续构建其他ServiceMethod属性,需要注意其他抛出异常的情况
返回类型不能是一个Response
httpMethod注解不能为空
如果请求中没有body,不能使用Multipart和FormEncoded
参数类型不能是基本类型和泛型
参数不能没有注解
URL不能为空
Form-encoded方法至少包含一个@Field注解
Multipart方法至少包含一个@Part注解
满足以上要求,才能正确构建ServiceMethod。
ServiceMethod loadServiceMethod(Method method) {
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError(&'&
+ Utils.getRawType(responseType).getName()
+ &' is not a valid response body type. Did you mean ResponseBody?&);
responseConverter = createResponseConverter();
网络请求处理
方法解析完成之后,调用CallAdapter的adapt方法返回Call
内部构建如下
public CallAdapter&Call&?&& get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter&Call&?&&() {
@Override public Type responseType() {
return responseT
@Override public &R& Call&R& adapt(Call&R& call) {
return new ExecutorCallbackCall&&(callbackExecutor, call);
}此时并没有发起请求,只是构建除了call,具体来说构建的是ExecutorCallbackCall,真正用来执行请求的是call内部的代理delegate,这个代理的真实身份是OkHttpCall,Retrofit2相当于将请求全权交给OKhttp处理,异步请求enqueue方法,同步请求execute方法都是执行的Okhttpclient对应的方法,
一下是okhttp请求的真实创建方法
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException(&Call.Factory returned null.&);
异步执行完之后,利用callbackExecutor将回调抛回主线程。
Retrofit2比Retrofit简化了很多,但是功能却更加强大了。真的非常奇妙。作为网络请求框架,整个代码中居然没有用线程池,因为Okhttp本身对异步处理已经做的很好了。充分发挥了其它模块的功能,简化了自身逻辑。
欢迎扫描二维码,关注公众号
本文已收录于以下专栏:
相关文章推荐
File 类定义了与平台无关的方法来操作文件。java的目录被当成一种特殊的文件,list方法返回目录中的所有目录和文件名。DOS下的路径分隔符为/,Unix下的路径分隔符为/,java都可识别。  ...
在 android开源图表库MPAndroidChart文档翻译(上) 中,介绍了mpandroidchart的创建,回调方法,还有轴。这篇文章继续翻译剩余内容。
MPAndroidChart数据显示...
一、简介“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction)...
一、 简介Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,OkHttp现在已经得到Google官方认可,大量的app都采用O...
Retrofit是一套RESTful架构的Android(Java)客户端实现,基于注解,提供JSON to POJO(Plain Ordinary Java Object,简单Jav...
Retrofit网络请求框架要点总结概述
Retrofit2是利用接口、方法和注解参数来声明定义请求的。
默认采用OkHttp(retrofit1.x中用的是Square包下的,retrofit2...
前言Hello,我是 JessYan,作为一个喜欢探索新颖解决方案的我,在 上篇文章 中,向大家介绍了怎样通过一行代码即可实现上传下载以及 Glide 进度监听,现在又给大家带来了另一项大家都很期待的...
就目前来说Retrofit2使用的已相当的广泛,那么我们先来了解下两个问题:1 . 什么是Retrofit?Retrofit是针对于Android/Java的、基于okHttp的、一种轻量级且安全的、...
转载请标明出处:
http://blog.csdn.net/lmj/article/details/;
本文出自:【张鸿洋的博客】
他的最新文章
讲师:王哲涵
讲师:韦玮
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 android retrofit请求 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信