我觉得华为是不是可以出一个杨颖抠图怎么看出来换背景

Android网络请求发展简史和RxJava+Retrofit+OkHttp实践_Android开发_动态网站制作指南
Android网络请求发展简史和RxJava+Retrofit+OkHttp实践
来源:人气:20
Android开发网络使用小结
Android 作为与IOS并驾齐驱的一个智能手机平台,在将近十年的时间内有了长足的发展,而这两大平台之所以能PK掉当年盛极一时的诺基亚及其使用的塞班系统,基于网络的丰富的功能功不可没。做了几年Android开发后,今天把Android的网络使用小结一下。
Android 网络请求推荐使用和发展历史
2.2之前:HttpClient
2.3之后:HttpURLConnection
2013年Google IO大会后:Google官方团队推出的volley
OkHttp出现以后:OkHttp
Android6.0以后Google官方Api移除HttpClient(继续使用HttpClient及基于其封装的网络库会出异常)
现在:推荐retrofit+OkHttp
我负责的项目中实际使用的网络层封装为rx+retrofit+OkHttp,简述一下:
rxjava:负责订阅回调,将请求回调切到主线程、中间回调拦截处理:统一异常处理等;
Retrofit:网络请求框架,配合OkHttp使用,使得网络请求更方便、更强大;
OkHttp:与HttpClient和HttpURLConnection类似,最底层实际处理Http请求。
1 网络请求的原始方式
1.1 HttpClient
Apache公司提供的库,提供高效的、最新的、功能丰富的支持HTTP协议工具包,支持HTTP协议最新的版本和建议,是个很不错的开源框架,封装了Http的请求,参数,内容体,响应等,拥有众多API。
最原始的网络请求方式,很强大但API很复杂,2.3之后Google官方便更推荐使用HttpURLConnection。在此不做展开。
1.2 HttpURLConnection
Sun公司提供的库,也是Java的标准类库java.net中的一员,但这个类什么都没封装,用起来很原始,若需要高级功能,则会显得不太方便,比如重访问的自定义,会话和cookie等一些高级功能。
在Android平台,Android2.2版本之前,HttpURLConnection还不太完善,存在一些问题,最好的请求方式是HttpClient,Android2.3版本之后,HttpURLConnection功能趋于完善,成为官方推荐的网络请求方式,很多开源网络库的封装也是选择在2.3版本后网络请求最终用HttpURLConnection的方式,例如Google官方推出的网络框架Volley。
具体HttpClient和HttpURLConnection的区别可以参考这篇文章:HttpClient和HttpURLConnection的区别(点击查看)
HttpURLConnection 请求网络代码示例:
* 基于HttpURLConnection的Http请求的工具类
public class HttpUtils {
ivate static final int TIMEOUT_IN_MILLIONS = 5000;
public interface CallBack {
void onRequestComplete(String result);
* 异步的Get请求
* @param urlStr
* @param callBack
public static void doGetAsyn(final String urlStr, final CallBack callBack) {
new Thread() {
public void run() {
String result = doGet(urlStr);
if (callBack != null) {
callBack.onRequestComplete(result);
} catch (Exception e) {
e.printStackTrace();
}.start();
* 异步的Post请求
* @param urlStr
* @param params
* @param callBack
* @throws Exception
public static void doPostAsyn(final String urlStr, final String params,
final CallBack callBack) throws Exception {
new Thread() {
public void run() {
String result = doPost(urlStr, params);
if (callBack != null) {
callBack.onRequestComplete(result);
} catch (Exception e) {
e.printStackTrace();
}.start();
* Get请求,获得返回数据
* @param urlStr
* @throws Exception
public static String doGet(String urlStr) {
HttpURLConnection conn =
InputStream is =
ByteArrayOutputStream baos =
url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(TIMEOUT_IN_MILLIONS);
conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);
conn.setRequestMethod("GET");
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
if (conn.getResponseCode() == 200) {
is = conn.getInputStream();
baos = new ByteArrayOutputStream();
int len = -1;
byte[] buf = new byte[128];
while ((len = is.read(buf)) != -1) {
baos.write(buf, 0, len);
baos.flush();
return baos.toString();
throw new RuntimeException(" responseCode is not 200 ... ");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null)
is.close();
} catch (IOException e) {
if (baos != null)
baos.close();
} catch (IOException e) {
conn.disconnect();
* 向指定 URL 发送POST方法的请求
* @param url
发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
* @throws Exception
public static String doPost(String url, String param) {
PrintWriter out =
BufferedReader in =
String result = "";
URL realUrl = new URL(url);
// 打开和URL之间的连接
HttpURLConnection conn = (HttpURLConnection) realUrl
.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"/x-www-form-urlencoded");
conn.setRequestProperty("charset", "utf-8");
conn.setUseCaches(false);
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setReadTimeout(TIMEOUT_IN_MILLIONS);
conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);
if (param != null && !param.trim().equals("")) {
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
while ((line = in.readLine()) != null) {
} catch (Exception e) {
e.printStackTrace();
// 使用finally块来关闭输出流、输入流
if (out != null) {
out.close();
if (in != null) {
in.close();
} catch (IOException ex) {
ex.printStackTrace();
2 网络请求的进阶模式
2.1 Volley
Google官方于2013年 Google IO大会上推出的 网络访问框架,现已经不推荐使用。了解可以参考这篇文章:Volley 解析
2.2 其他封装的网络请求框架
与volley类似的第三方封装的网络请求框架有FinalHttp、android-async-http等,基本都是基于HttpClient和HttpURLConnection封装的,本质上没有太大区别,每个库封装的成都和使用的便利性和灵活性不同。
3 网络请求的时尚模式(RxJava+Retrofit+OkHttp实践)
3.1 OkHttp
OkHttp是一款优秀的HTTP框架,它支持get请求和post请求,支持基于Http的文件上传和下载,支持加载图片,支持下载文件透明的GZ压缩,支持响应缓存避免重复的网络请求,支持使用连接池来降低响应延迟问题。
OkHttp的入门和集成请参考这篇官方教程:OkHttp 官方教程解析 - 彻底入门 OkHttp 使用
3.2 与Retrofit结合的OkHttp
使用OkHttp的项目多半会配合同是 出的Retrofit,两者相结合,更加强大。
而我在实际开发中使用的网络框架是rxJava+Retrofit+OkHttp的结合。
不废话,直接上代码:
先看调用示例:
步骤一:在ApiService中添加接口
* 1 写上请求网络的方法名rxGetTest、接口的返回参数的Json反序列化出的Bean对象WeatherInfo;
* 2 @GET参数上配置上这个接口具体请求Url的后缀,如@GET(“data/sk/.html”);
实际请求的url为 .cn/data/sk/.html
retrofit中配置的BaseUrl为.cn/ 所以此处只写去除Baseurl的后缀即可。
package com.bailiangjin.httprequest.
import com.bailiangjin.httprequest.net.rxretrofitokhttp.design.BaseD
import com.bailiangjin.httprequest.rxokdemo.model.PostI
import com.bailiangjin.httprequest.rxokdemo.model.WeatherI
import java.util.M
import retrofit2.http.FieldM
import retrofit2.http.FormUrlE
import retrofit2.http.GET;
import retrofit2.http.POST;
import rx.O
* 网络请求Service 方法汇总 将调用的方法在此处进行rx绑定
* Created by bailiangjin on .
public interface ApiService {
@GET("data/sk/.html")
Observable&WeatherInfo& rxGetTest();
@GET("query?type=yuantong&postid=")
Observable&PostInfo& rxGetPostInfo();
* Post方式请求需要添加 FormUrlEncoded标识
* @param map
@FormUrlEncoded
@POST("/")
Observable&BaseData&PostInfo&& rxPostTest(@FieldMap Map&String, String& map);
第二部 请求网络 代码如下,是不是很爽:
//get调用方式示例
RxRequestHelper.requestNotDealCommonError(getWeatherApiService().rxGetTest(), new CommonResponseSubscriber() {
public void onNext(WeatherInfo weatherInfoBaseData) {
//拿到回调的数据具体处理
//post调用方式示例
* post示例 不使用公有异常处理 post只写上了使用方式 具体测试请使用自己的接口测试
* @param subscriber
对于上面代码中用到的getWeatherApiService() 其实是一个ApiService对象,是通过如下代码生成的,如果BaseUrl一致 只用一个ApiService即可,写好一次,以后每次添加接口只走上面两部即可,如果请求的接口BaseUrl不只一个那也没关系,添加一行代码即可添加一个新的BaseUrl的Retrofit,是不是很强大,其实这主要是借助了枚举,具体可以看工程中的代码,在此不展开讨论了。
package com.bailiangjin.httprequest.
import com.bailiangjin.httprequest.net.rxretrofitokhttp.tools.RetrofitC
import retrofit2.R
* 天气Service
* Created by bailiangjin on .
public enum WeatherApiService {
private ApiService apiS
WeatherApiService() {
retrofit = RetrofitCollection.WEATHER_INSTANCE.getRetrofit();
apiService = retrofit.create(ApiService.class);
public ApiService getApiService() {
return apiS
public String getBaseUrl() {
return retrofit.baseUrl().toString();
其他核心代码如下:
package com.bailiangjin.httprequest.net.rxretrofitokhttp.
import java.io.IOE
import java.util.concurrent.TimeU
import okhttp3.CacheC
import okhttp3.I
import okhttp3.OkHttpC
import okhttp3.R
import okhttp3.R
import okhttp3.logging.HttpLoggingI
* 最底层的 OKHttpClient
* Created by bailiangjin on .
public enum MyOkHttpClient {
private OkHttpClient okHttpC
MyOkHttpClient() {
okHttpClient = new OkHttpClient.Builder()
//.cache(cache)
//禁用okhttp自身的的缓存
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(new MyInterceptor())
.addInterceptor(new HttpLoggingInterceptor())
public OkHttpClient getOkHttpClient() {
return okHttpC
static class MyInterceptor implements Interceptor {
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
//添加header
//CommonNetUtils.addHeader(builder);
//修改请求为只从网络中读数据
Request request = builder
.cacheControl(CacheControl.FORCE_NETWORK).build();
return chain.proceed(request);
package com.bailiangjin.httprequest.net.rxretrofitokhttp.
import retrofit2.R
import retrofit2.adapter.rxjava.RxJavaCallAdapterF
import retrofit2.converter.gson.GsonConverterF
* Retrofit 集合 可以通过添加枚举元素的方式 方便地添加 不同 root url的 retrofit
* @author bailiangjin
public enum RetrofitCollection {
WEATHER_INSTANCE(“.cn/“),
EXPRESS_INSTANCE(“/“);
RetrofitCollection(String baseUrl) {
retrofit = new Retrofit.Builder()
.client(MyOkHttpClient.INSTANCE.getOkHttpClient())
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//也可以添加自定义的RxJavaCallAdapterFactory
public Retrofit getRetrofit() {
package com.bailiangjin.httprequest.net.rxretrofitokhttp.
import com.bailiangjin.httprequest.net.rxretrofitokhttp.design.BaseD
import com.bailiangjin.httprequest.net.monE
import rx.O
import rx.S
import rx.android.schedulers.AndroidS
import rx.schedulers.S
* 网络请求的RxHelper类 功能 1、将网络请求的回调绑定到主线程 2、进行统一的异常处理 可根据需要选择
* Created by bailiangjin on .
public class RxRequestHelper {
* 绑定回调到mainthread 并统一处理异常
* @param observable
* @param subscriber
* @param &T&
public static &T& Observable requestDealCommonError(Observable&BaseData&T&& observable, Subscriber&BaseData&T&& subscriber) {
mapCommonErrors(observable);
setSubscribeToAndroidMainThread(observable, subscriber);
* 绑定回调到mainthread 不统一处理异常
* @param observable
* @param subscriber
* @param &T&
public static &T& void requestNotDealCommonError(Observable&T& observable, Subscriber&T& subscriber) {
setSubscribeToAndroidMainThread(observable, subscriber);
* 将回调切换到MainThread
* @param observable
* @param subscriber
* @param &T&
private static &T& void setSubscribeToAndroidMainThread(Observable&T& observable, Subscriber&T& subscriber) {
observable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
* 异常统一处理
* @param observable
* @param &T&
private static &T& void mapCommonErrors(Observable&BaseData&T&& observable) {
observable.map(new CommonErrors&T&());
篇幅问题,文章里只贴了部分代码,想实际体验请clone我的github项目代码具体运行:Github网络请求代码链接:AndroidHttpRequest (点击查看)
3.3 其他基于OkHttp的开源库
其实OkHttp并非一个网络框架,他的属性和功能与HttpClient和HttpURLConnection类似,都是Http请求网络的具体方式,当OkHttp广泛使用后,也会有很多基于OkHttp封装的可能更方便的第三方框架,这里就不在展开,感兴趣的可以Google一下。
本文所有代码都可到我的github项目AndroidHttpRequest中查看。
更多精彩文章推荐:
Android Activity 全局管理 终极解决方案
Android BaseAdapter的极简封装
优质网站模板如何高效的使用Okhttp - 推酷
如何高效的使用Okhttp
是一个在开发可汗学院Android APP过程中非常重要的依赖库。它的默认的配置为我们提供了非常重要实用功能,下面一些步骤我们可以让Okhttp提供更多功能使用灵活和内省能力。
1. 启用文件系统上的响应缓存
默认情况下,Okhttp不支持响应缓存,包括HTTP Cache-Control头允许缓存响应。因此,客户端通过一次又一次的请求相同的资源浪费时间和带宽。而不是简单地读取初始响应后缓存的副本。
要在文件系统中启用响应缓存,需要配置com.squareup.okhttp.Cache实例,并把它传递给你的OkHttpClient实例的setCache方法。你必须初始化缓存与存放目录的文件,并以字节为单位的最大值。
响应返回数据可以写入给定目录文件,如果一个响应的缓存超过了给定的大小。我们可以采取
我们可以在
的回复。我们可以通过context.getCacheDir()在子目录中缓存我们的响应:
// Base directory recommended by /a/717.
// Guard against null, which is possible according to
// /d/msg/android-developers/-694j87eXVU/YYs4b6kextwJ and
// /q/717.
final @Nullable File baseDir = context.getCacheDir();
if (baseDir != null) {
final File cacheDir = new File(baseDir, &HttpResponseCache&);
okHttpClient.setCache(new Cache(cacheDir, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE));
// Base directory recommended by /a/717.
// Guard against null, which is possible according to
// /d/msg/android-developers/-694j87eXVU/YYs4b6kextwJ and
// /q/717.
final @NullableFilebaseDir = context.getCacheDir();
if (baseDir != null) {
&&final FilecacheDir = new File(baseDir, &HttpResponseCache&);
&&okHttpClient.setCache(new Cache(cacheDir, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE));
在可汗学院的程序中我们指定 HTTP_RESPONSE_DISK_CACHE_MAX_SIZE as 10 * 1024 * 1024 , or 10 MB的大小
2. 集成Stetho
是Facebook的一个可爱的库,可以使用Chrome浏览器的Chrome开发人员工具功能来检查你的Andr oid应用程序。
Stetho除了允许你检查你的应用程序的SQLite数据库,还可以查看View的层次结构。允许你检查由OkHttp发起的每个请求和响应:
这种自省机制是确保服务器返回允许资源缓存的HTTP头是非常有用的,以及验证没有请求时,保证缓存的资源存在。
要想使用Stetho,只需添加一个StethoInterceptor实例的网络拦截器列表:
okHttpClient.networkInterceptors().add(new StethoInterceptor());
okHttpClient.networkInterceptors().add(new StethoInterceptor());
然后,运行应用程序,打开浏览器后,输入chrome://inspect。然后你就会看到应用程序的设备和标识符的列表。然后鼠标右键选择inspect 打开开发者工具,然后打开新的tab,开始监控OkHttp请求。
3. 使用Picasso 和 Retrofit
你可能使用过
来加载网络图片,或者使用
来简化发出请求和解码响应。这些第三方库将隐式地创建自己的OkHttpClient供内部使用,如果你不明确指定一个。
Picasso&version 2.5.2的OkHttpDownloader类:
private static OkHttpClient defaultOkHttpClient() {
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(Utils.DEFAULT_CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setReadTimeout(Utils.DEFAULT_READ_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setWriteTimeout(Utils.DEFAULT_WRITE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
private static OkHttpClientdefaultOkHttpClient() {
&&OkHttpClientclient = new OkHttpClient();
&&client.setConnectTimeout(Utils.DEFAULT_CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
&&client.setReadTimeout(Utils.DEFAULT_READ_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
&&client.setWriteTimeout(Utils.DEFAULT_WRITE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
Retrofit也有类似的工厂方法来创建自己的OkHttpClient。
图片一般在应用程序中需要加载的比较大的资源。尽管Picasso自己维护它的LRU机制来缓存图片,在内存中严格执行。如果客户端尝试使用Picasso来加载图片。Picasso会找不到其在内存中缓存图像,然后将委托加载该图片到它的内部OkHttpClient实例。并且默认情况下该实例将始终从服务器加载图片资源。
作为defaultOkHttpClient的方法不能与上面提到的文件系统中的响应缓存配置结合起来。
指定你自己的OkHttpClient实例允许返回数据从文件系统缓存响应,图片不会从服务器加载。这是非常重要的在程序第一次启动以后。这个时候Picasso的内存缓存是冷的。所以它会频繁的委托OkHttpClient实例去加载图片。
这就需要构建配置了您Picasso 的OkHttpClient实例,如果你在你的代码中使用
Picasso.with(context).load(...)
Picasso.with(context).load(...)
加载图片,你是用的是Picasso的单例模式。这是通过with方法懒汉模式地实例化并配置自己的OkHttpClient。因此,我们必须使我们自己的Picasso实例在单例之前通过wiht方法调用。
实现这个,可以简单的将OkHttpClient实例封装在OkHttpDownloader中,然后传递给 Picasso.Builder 实例的downloader方法。
final Picasso picasso = new Picasso.Builder(context)
.downloader(new OkHttpDownloader(okHttpClient))
// The client should inject this instance whenever it is needed, but replace the singleton
// instance just in case.
Picasso.setSingletonInstance(picasso);
final Picassopicasso = new Picasso.Builder(context)
&&&&.downloader(new OkHttpDownloader(okHttpClient))
&&&&.build();
// The client should inject this instance whenever it is needed, but replace the singleton
// instance just in case.
Picasso.setSingletonInstance(picasso);
在Retrofit中要使用OkHttpClient实例,需要改造1.9.x的一个RestAdapter,需要将OkHttpClient封装OkClient的实例中。然后把它传递给RestAdapter.Builder实例的setClient方法。
restAdapterBuilder.setClient(new OkClient(httpClient));
restAdapterBuilder.setClient(new OkClient(httpClient));
在 Retrofit 2.0中只需要简单的将OkHttpClient传递给Retrofit.Builder实例的client方法。
在可汗学院的APP中我们通过
依赖注入来确保我们只有一个OkHttpClient的实例。这种方法同样也适用于Picasso和Retrofit我们提供了一个为OkHttpClient实例提供单例模式的注解示例:
@Singleton
public OkHttpClient okHttpClient(final Context context, ...) {
final OkHttpClient okHttpClient = new OkHttpClient();
configureClient(okHttpClient, ...);
return okHttpC
@Singleton
public OkHttpClientokHttpClient(final Contextcontext, ...) {
&&final OkHttpClientokHttpClient = new OkHttpClient();
&&configureClient(okHttpClient, ...);
&&return okHttpC
OkHttpClient将会通过Dagger的注解创建一个实例提供给我们的Picasso和Retrofit。
4.指定一个用户代理拦截器
日志文件和分析为我们提供了更多有用的信息,当客户在每个请求提供详细的User-Agent header值的时候。默认情况下,Okhttp包含User-Agent值只有在特定的Okhttp版本中。为了指定我们自己的user agent。首先创建拦截器的替换值,
public final class UserAgentInterceptor implements Interceptor {
private static final String USER_AGENT_HEADER_NAME = &User-Agent&;
private final String userAgentHeaderV
public UserAgentInterceptor(String userAgentHeaderValue) {
this.userAgentHeaderValue = Preconditions.checkNotNull(userAgentHeaderValue);
public Response intercept(Chain chain) throws IOException {
final Request originalRequest = chain.request();
final Request requestWithUserAgent = originalRequest.newBuilder()
.removeHeader(USER_AGENT_HEADER_NAME)
.addHeader(USER_AGENT_HEADER_NAME, userAgentHeaderValue)
return chain.proceed(requestWithUserAgent);
public final class UserAgentInterceptor implements Interceptor {
&&private static final String USER_AGENT_HEADER_NAME = &User-Agent&;
&&private final String userAgentHeaderV
&&public UserAgentInterceptor(String userAgentHeaderValue) {
&&&&this.userAgentHeaderValue = Preconditions.checkNotNull(userAgentHeaderValue);
&&@Override
&&public Responseintercept(Chainchain) throws IOException {
&&&&final RequestoriginalRequest = chain.request();
&&&&final RequestrequestWithUserAgent = originalRequest.newBuilder()
&&&&&&&&.removeHeader(USER_AGENT_HEADER_NAME)
&&&&&&&&.addHeader(USER_AGENT_HEADER_NAME, userAgentHeaderValue)
&&&&&&&&.build();
&&&&return chain.proceed(requestWithUserAgent);
为了创建User-Agent header值人然后传递给UserAgentInterceptor的构造器,使用你得到的任何信息。
我们可以使用:
android 的系统信息可以清晰的传递出这是一台android 设备
Build.MODEL 或者“制造商提供的用户可见最终可见的名称”
Build.BRAND或者“消费者可见的品牌与产品/硬件相关信息”
Build.VERSION.SDK_INT或者“消费者可见的Android提供的SDK版本号”
BuildConfig.APPLICATION_ID
BuildConfig.VERSION_NAME
BuildConfig.VERSION_CODE
最后三个值由的applicationID,VERSIONCODE和VERSIONNAME的值在我们的Gradle build脚本中
了解更多信息可以查看
请注意,如果您的应用程序使用的是WebView,您可以配置使用相同的 User-Agent header值,你可以通过下面方法创建UserAgentInterceptor:
WebSettings settings = webView.getSettings();
settings.setUserAgentString(userAgentHeaderValue);
WebSettingssettings = webView.getSettings();
settings.setUserAgentString(userAgentHeaderValue);
5.指定合理的超时
2.5.0版本之前,OkHttp请求默认为永不超时。2.5.0版本开始如果建立连接请求超时,如果从连接读取下一个字节或写入的下一个字节到连接,花费超过10秒,就终止。这样做需要更新到2.5.0版本我们就不需要在我们的代码中修改bug。原因很简单是我因为我们第一次使用的时候使用了错误的路径。
要覆盖这些默认值,可以分别调用setConnectTimeout,setReadTimeout或setWriteTimeout。
需要注意的是Picasso和Retrofit为OkHttpClient实例指定不同的超时值时,默认情况下,Picasso指定:
连接超过15秒.
读取超过20秒
写入超过20秒
而Retrofit指定:
连接超过15秒.
读取超过20秒
没有写入超时
通过配置Picasso和Retrofit自己的OkHttpClient实例你可以确保所有的请求超时是一致的
Okhttp默认的配置为我们提供了非常重要实用功能。通过采用上述步骤,你可以增加它的灵活性和内省的能力并提高应用程序的质量。
如何高效的使用Okhttp
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致

我要回帖

更多关于 ps抠图后怎么拿出来 的文章

 

随机推荐