开源框架之一第一篇:OKhttp解析,这些你又了解多少呢?

谷歌认证:2021全新Android开源框架权威排行榜(附源码解析) 随着蓬勃发展的开源时代的到来,为了减少开发成本,提高开发效率,越来越多的公司使用各种开源项目,作为开发者,如果能充分利用好开源项目中的资源,不仅能提高实践能力,专业知识水平,还能从中其中学到的优秀的架构思想。 但是开源界的Android框架实在太多了,多到近乎疯狂的地步,让我们在选择的时候不知所措。特此整理了这份《2021全新Android百大开源框架源码解析》,帮助大家在使用时可以快速查找。 如果你能熟练运用这里面所提到的框架,在遇到某种需求的时候,立刻会拿出“最优秀的框架”去解决,意味着你离高级工程师不 阅读详情
一、整体思路

从使用方法出发,首先是怎么使用,其次是我们使用的功能在内部是如何实现的, 实现方案上有什么技巧,有什么范式。全文基本上是对 OkHttp 源码的一个分析与 导读,非常建议大家下载 OkHttp 源码之后,跟着本文,过一遍源码。对于技巧和 范式,由于目前我的功力还不到位,分析内容没多少,欢迎大家和我一起讨论。

本部分内容是关于Android进阶的一些知识总结,涉及到的知识点比较杂,不过都 是面试中几乎常问的知识点,也是加分的点。 关于这部分内容,可能需要有一些具体的项目实践。在面试的过程中,结合具体自 身实践经历,才能更加深入透彻的描绘出来

相关内容后续GitHub更新,想冲击金三银四的小伙伴可以找找看看,欢迎star
(顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找)
https://github.com/xiangjiana/Android-MS
更多完整项目下载。未完待续。源码。图文知识后续上传github。
可以点击关于我联系我获取

首先放一张完整流程图(看不懂没关系,慢慢往后看):

二、基本用例

来自OKHTTP官方网站

2.1.创建 OkHttpClient 对象
  OkHttpClient client = new OkHttpClient();

咦,怎么不见 builder?莫急,且看其构造函数:

  public OkHttpClient() { 
    this(new Builder()); 
  }

原来是方便我们使用,提供了一个“快捷操作”,全部使用了默认的配 置。 OkHttpClient.Builder 类成员很多,后面我们再慢慢分析,这里先暂时略 过:

  public Builder() { 
    dispatcher = new Dispatcher(); 
    protocols = DEFAULT_PROTOCOLS; 
    connectionSpecs = DEFAULT_CONNECTION_SPECS; 
    proxySelector = ProxySelector.getDefault(); 
    cookieJar = CookieJar.NO_COOKIES; 
    socketFactory = SocketFactory.getDefault(); 
    hostnameVerifier = OkHostnameVerifier.INSTANCE; 
    certificatePinner = CertificatePinner.DEFAULT; 
    proxyAuthenticator = Authenticator.NONE; 
    authenticator = Authenticator.NONE; 
    connectionPool = new ConnectionPool(); 
    dns = Dns.SYSTEM; 
    followSslRedirects = true; 
    followRedirects = true; 
    retryOnConnectionFailure = true; 
    connectTimeout = 10_000; 
    readTimeout = 10_000; 
    writeTimeout = 10_000; 
  }
2.2.发起 HTTP 请求
  String run(String url) throws IOException { 
    Request request = new Request.Builder()
       .url(url) 
       .build(); 
  Response response = client.newCall(request).execute(); 
  return response.body().string(); 
  }

OkHttpClient 实现了 Call.Factory ,负责根据请求创建新的 Call 。
那我们现在就来看看它是如何创建 Call 的:

  /**
    * Prepares the {@code request} to be executed at some point in the future. 
    */ 
  @Override public Call newCall(Request request) { 
    return new RealCall(this, request); 
  }

如此看来功劳全在 RealCall 类了,下面我们一边分析同步网络请求的过程,一边 了解 RealCall 的具体内容。

2.2.1.同步网络请求

我们首先看 RealCall#execute :

  @Override public Response execute() throws IOException { 
    synchronized (this) { 
      if (executed) throw new IllegalStateException("Already Execu ted"); 
          // (1) 
      executed = true; 
    }
    try { 
      client.dispatcher().executed(this); 
         // (2) 
      Response result = getResponseWithInterceptorChain(); 
        // (3) 
      if (result == null) throw new IOException("Canceled"); 
      return result; 
    } finally { 
    client.dispatcher().finished(this); 
       // (4) 
    } 
   }

这里我们做了 4 件事:

  1. 检查这个 call 是否已经被执行了,每个 call 只能被执行一次,如果想要一个完 全一样的 call,可以利用 call#clone 方法进行克隆。
  2. 利用 client.dispatcher().executed(this) 来进行实际执 行 dispatcher 是刚才看到的 OkHttpClient.Builder 的成员之一,它的文 档说自己是异步 HTTP 请求的执行策略,现在看来,同步请求它也有掺和。
  3. 调用 getResponseWithInterceptorChain() 函数获取 HTTP 返回结果,从 函数名可以看出,这一步还会进行一系列“拦截”操作。
  4. 最后还要通知 dispatcher 自己已经执行完毕。

dispatcher 这里我们不过度关注,在同步执行的流程中,涉及到 dispatcher 的内容 只不过是告知它我们的执行状态,比如开始执行了(调用 executed ),比如执行 完毕了(调用 finished ),在异步执行流程中它会有更多的参与。

真正发出网络请求,解析返回结果的,还 是 getResponseWithInterceptorChain:

   private Response getResponseWithInterceptorChain() throws IOExce ption { 
     // Build a full stack of interceptors. 
     List<Interceptor> interceptors = new ArrayList<>(); 
     interceptors.addAll(client.interceptors()); 
     interceptors.add(retryAndFollowUpInterceptor); 
     interceptors.add(new BridgeInterceptor(client.cookieJar())); 
     interceptors.add(new CacheInterceptor(client.internalCache())) ; 
     interceptors.add(new ConnectInterceptor(client)); 
     if (!retryAndFollowUpInterceptor.isForWebSocket()) { 
       interceptors.addAll(client.networkInterceptors()); 
     }
     interceptors.add(new CallServerInterceptor( 
         retryAndFollowUpInterceptor.isForWebSocket())); 
     Interceptor.Chain chain = new RealInterceptorChain( 
         interceptors, null, null, null, 0, originalRequest); 
     return chain.proceed(originalRequest); 
   }

Interceptor 是 OkHttp 最核心的一个东西,不要误以为它只负责拦截请求 进行一些额外的处理(例如 cookie),实际上它把实际的网络请求、缓存、透明压 缩等功能都统一了起来,每一个功能都只是一个 Interceptor ,它们再连接成一 个 Interceptor.Chain ,环环相扣,最终圆满完成一次网络请求。

从 getResponseWithInterceptorChain 函数我们可以看 到 Interceptor.Chain 的分布依次是:

  1. 在配置 OkHttpClient 时设置的 interceptors ;
  2. 负责失败重试以及重定向的 RetryAndFollowUpInterceptor;
  3. 负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换 为用户友好的响应的 BridgeInterceptor ;
  4. 负责读取缓存直接返回、更新缓存的 CacheInterceptor ;
  5. 负责和服务器建立连接的 ConnectInterceptor ;
  6. 配置 OkHttpClient 时设置的 networkInterceptors ;
  7. 负责向服务器发送请求数据、从服务器读取响应数 据 CallServerInterceptor 。

在这里,位置决定了功能,最后一个 Interceptor 一定是负责和服务器实际通讯的, 重定向、缓存等一定是在实际通讯之前的。 责任链模式在这个 Interceptor 链条中得到了很好的实践。

它包含了一些命令对象和一系列的处理对象,每一个处理对象决定它能处理哪 些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处 理对象。该模式还描述了往该处理链的末尾添加新的处理对象的方法。

对于把 Request 变成 Response 这件事来说,每个 Interceptor 都可能完成这 件事,所以我们循着链条让每个 Interceptor 自行决定能否完成任务以及怎么完 成任务(自力更生或者交给下一个 Interceptor )。这样一来,完成网络请求这 件事就彻底从 RealCall 类中剥离了出来,简化了各自的责任和逻辑。两个字:优 雅!

责任链模式在安卓系统中也有比较典型的实践,例如 view 系统对点击事件 (TouchEvent)的处理。

回到 OkHttp,在这里我们先简单分析一 下 ConnectInterceptor 和 CallServerInterceptor ,看看 OkHttp 是怎么进 行和服务器的实际通信的。

2.2.1.1.建立连接: ConnectInterceptor
  @Override public Response intercept(Chain chain) throws IOExcept ion { 
     RealInterceptorChain realChain = (RealInterceptorChain) chain; 
     Request request = realChain.request(); 
     StreamAllocation streamAllocation = realChain.streamAllocation ();
     // We need the network to satisfy this request. Possibly for v alidating a conditional GET. boolean doExtensiveHealthChecks = !request.method().equals("GE T");
     HttpCodec httpCodec = streamAllocation.newStream(client, doExt ensiveHealthChecks); 
     RealConnection connection = streamAllocation.connection(); 
     return realChain.proceed(request, streamAllocation, httpCodec, connection); 
   }

实际上建立连接就是创建了一个 HttpCodec 对象,它将在后面的步骤中被使用, 那它又是何方神圣呢?它是对 HTTP 协议操作的抽象,有两个实 现: Http1Codec 和 Http2Codec ,顾名思义,它们分别对应 HTTP/1.1 和 HTTP/2 版本的实现。

在 Http1Codec 中,它利用Okio对 Socket 的读写操作进行封装,Okio 以后有机 会再进行分析,现在让我们对它们保持一个简单地认识:它 对 java.io 和 java.nio 进行了封装,让我们更便捷高效的进行 IO 操作。

而创建 HttpCodec 对象的过程涉及 到 StreamAllocation、 RealConnection ,代码较长,这里就不展开,这个过 程概括来说,就是找到一个可用的 RealConnection ,再利 用 RealConnection 的输入输出( BufferedSource 和 BufferedSink )创 建 HttpCodec 对象,供后续步骤使用。

2.2.1.2.发送和接收数据: CallServerInterceptor
  @Override public Response intercept(Chain chain) throws IOExcept ion {
  HttpCodec httpCodec = ((RealInterceptorChain) chain).httpStrea m();
  StreamAllocation streamAllocation = ((RealInterceptorChain) ch ain).streamAllocation(); 
  Request request = chain.request();
  long sentRequestMillis = System.currentTimeMillis(); httpCodec.writeRequestHeaders(request);
  if (HttpMethod.permitsRequestBody(request.method()) && request .body() != null) {
    Sink requestBodyOut = httpCodec.createRequestBody(request, r equest.body().contentLength());
    BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
    request.body().writeTo(bufferedRequestBody); 
    bufferedRequestBody.close();
  }
    ......
    // 省略部分检查代码
    return response; 
  }

我们抓住主干部分:

  1. 向服务器发送 request header;
  2. 如果有 request body,就向服务器发送;
  3. 读取 response header,先构造一个 Response 对象;
  4. 如果有 response body,就在 3 的基础上加上 body 构造一个新 的 Response 对象;

这里我们可以看到,核心工作都由 HttpCodec 对象完成,而 HttpCodec实际上 利用的是 Okio,而 Okio 实际上还是用的 Socket ,所以没什么神秘的,只不过一 层套一层,层数有点多。

其实 Interceptor 的设计也是一种分层的思想,每个 Interceptor 就是一层。 为什么要套这么多层呢?分层的思想在 TCP/IP 协议中就体现得淋漓尽致,分层简 化了每一层的逻辑,每层只需要关注自己的责任(单一原则思想也在此体现),而 各层之间通过约定的接口/协议进行合作(面向接口编程思想),共同完成复杂的任 务

简单应该是我们的终极追求之一,尽管有时为了达成目标不得不复杂,但如果有另 一种更简单的方式,我想应该没有人不愿意替换。

2.2.2.发起异步网络请求
  client.newCall(request).enqueue(new Callback() { 
     @Override 
     public void onFailure(Call call, IOException e) { 
     }
     @Override 
     public void onResponse(Call call, Response response) throws IOException { 
       System.out.println(response.body().string()); 
     } 
   }); 
   // RealCall#enqueue 
   @Override public void enqueue(Callback responseCallback) { 
       synchronized (this) { 
         if (executed) throw new IllegalStateException("Already Execu ted");
          executed = true; 
       }
       client.dispatcher().enqueue(new AsyncCall(responseCallback)); 
   }
   // Dispatcher#enqueue 
   synchronized void enqueue(AsyncCall call) { 
        if (runningAsyncCalls.size() < maxRequests && runningCallsForH ost(call) < maxRequestsPerHost) { 
          runningAsyncCalls.add(call); executorService().execute(call); 
        } else { 
          readyAsyncCalls.add(call); 
        } 
   }

这里我们就能看到 dispatcher 在异步执行时发挥的作用了,如果当前还能执行一个 并发请求,那就立即执行,否则加入 readyAsyncCalls 队列,而正在执行的请求 执行完毕之后,会调用 promoteCalls() 函数,来把 readyAsyncCalls 队列中 的 AsyncCall “提升”为 runningAsyncCalls ,并开始执行。

这里的 AsyncCall 是 RealCall 的一个内部类,它实现了 Runnable ,所以可 以被提交到 ExecutorService 上执行,而它在执行时会调 用 getResponseWithInterceptorChain() 函数,并把结果通 过 responseCallback 传递给上层使用者。

这样看来,同步请求和异步请求的原理是一样的,都是 在 getResponseWithInterceptorChain() 函数中通过 Interceptor 链条来实 现的网络请求逻辑,而异步则是通过 ExecutorService 实现。

2.3返回数据的获取

在上述同步( Call#execute() 执行之后)或者异步 ( Callback#onResponse() 回调中)请求完成之后,我们就可以 从 Response 对象中获取到响应数据了,包括 HTTP status code,status message,response header,response body 等。这里 body 部分最为特殊,因为 服务器返回的数据可能非常大,所以必须通过数据流的方式来进行访问(当然也提 供了诸如 string() 和 bytes() 这样的方法将流内的数据一次性读取完毕),而 响应中其他部分则可以随意获取。

响应 body 被封装到 ResponseBody 类中,该类主要有两点需要注意:

  1. 每个 body 只能被消费一次,多次消费会抛出异常;
  2. body 必须被关闭,否则会发生资源泄漏;

在2.2.1.2.发送和接收数据:CallServerInterceptor小节中,我们就看过了 body 相 关的代码:

  if (!forWebSocket || response.code() != 101) { 
     response = response.newBuilder() 
        .body(httpCodec.openResponseBody(response)) 
        .build(); 
  }

由 HttpCodec#openResponseBody 提供具体 HTTP 协议版本的响应 body, 而 HttpCodec 则是利用 Okio 实现具体的数据 IO 操作。

这里有一点值得一提,OkHttp 对响应的校验非常严格,HTTP status line 不能有任 何杂乱的数据,否则就会抛出异常,在我们公司项目的实践中,由于服务器的问 题,偶尔 status line 会有额外数据,而服务端的问题也毫无头绪,导致我们不得不 忍痛继续使用 HttpUrlConnection,而后者在一些系统上又存在各种其他的问题, 例如魅族系统发送 multi-part form 的时候就会出现没有响应的问题。

2.4.HTTP 缓存

在2.2.1.同步网络请求小节中,我们已经看到了 Interceptor 的布局,在建立连 接、和服务器通讯之前,就是 CacheInterceptor ,在建立连接之前,我们检查 响应是否已经被缓存、缓存是否可用,如果是则直接返回缓存的数据,否则就进行 后面的流程,并在返回之前,把网络的数据写入缓存。 这块代码比较多,但也很直观,主要涉及 HTTP 协议缓存细节的实现,而具体的缓 存逻辑 OkHttp 内置封装了一个 Cache 类,它利用 DiskLruCache ,用磁盘上的 有限大小空间进行缓存,按照 LRU 算法进行缓存淘汰,这里也不再展开。 我们可以在构造 OkHttpClient 时设置 Cache 对象,在其构造函数中我们可以指 定目录和缓存大小:

  public Cache(File directory, long maxSize);

而如果我们对 OkHttp 内置的 Cache 类不满意,我们可以自行实 现 InternalCache 接口,在构造 OkHttpClient 时进行设置,这样就可以使用 我们自定义的缓存策略了。

三、总结 OkHttp

还有很多细节部分没有在本文展开,例如 HTTP2/HTTPS 的支持等,但建 立一个清晰的概览非常重要。对整体有了清晰认识之后,细节部分如有需要,再单 独深入将更加容易。 在文章最后我们再来回顾一下完整的流程图:

  • OkHttpClient 实现 Call.Factory ,负责为 Request 创建 Call ;
  • RealCall 为具体的 Call 实现,其 enqueue() 异步接口通 过 Dispatcher 利用 ExecutorService 实现,而最终进行网络请求时和同 步 execute() 接口一致,都是通 过 getResponseWithInterceptorChain() 函数实现;
  • getResponseWithInterceptorChain() 中利用 Interceptor 链条,分层 实现缓存、透明压缩、网络 IO 等功能;

相关内容后续GitHub更新,想冲击金三银四的小伙伴可以找找看看,欢迎star
(顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找)
https://github.com/xiangjiana/Android-MS
更多完整项目下载。未完待续。源码。图文知识后续上传github。
可以点击关于我联系我获取

基于分数阶的图像边缘细节检测——边缘计算 在图像处理中,我们可以使用分数阶导数运算器来计算图像的分数阶梯度,从而得到更精确的边缘信息。通过使用基于分数阶的图像边缘细节检测方法,我们可以更准确地捕捉图像中的边缘细节信息。在这篇文章中,我们将介绍一种基于分数阶的方法来进行图像边缘细节检测,并提供相应的源代码实现。需要注意的是,以上提供的代码示例仅用于演示基于分数阶的图像边缘细节检测方法的实现。然后,我们读取了待处理的图像,并进行了预处理,如高斯模糊,以减少噪声的影响。最后,我们通过设置一个阈值,将梯度图像转化为二值化的边缘图像,并将结果显示出来。 阅读详情

相关推荐

kali破解WIFI密码

今天我们来学习一下通过kali和一个好的字典来破解WIFI密码。 声明:此教程仅供学习研究使用,严禁使用此技术进行非法行为 首先我们需要一个具有监听功能的无线网卡(这里我给大家推荐:rt3070) 本章实验通过虚拟机VMware进行: 先通过services.msc来打开VMware USB Arbitration Service 插上监听网卡,连接USB到虚...

#的博客 5808

OKHttp源码分析(三)之ResponseBody

一,概述在使用OKHttp访问网络时,无论是同步请求还是异步请求,返回结果都是Response对象,所有的说句都封装在这个对象中。 这个对象常用的方法有:int code = response.code();//获取响应码 String message = response.message();//获取响应消息 ResponseBody body = response.body();//获取响应

fightingXia的博客 1万+

智能车‘大脑’的诞生:揭秘电磁循迹代码背后的控制论与系统思维

本文深入探讨智能车电磁循迹系统的核心架构与控制原理,揭示了其作为精密闭环系统如何通过模块化设计、信号处理、PID控制算法及电机驱动实现自主导航。重点分析了电磁信号采集与处理流程框架,为开发者提供从理论到实践的全面指南。

arduino9maker的博客 531

六款值得推荐的android(安卓)开源框架简介

1、volley 项目地址 https://github.com/smanikandan14/Volley-demo  (1)  JSON,图像等的异步下载;  (2)  网络请求的排序(scheduling)  (3)  网络请求的优先级处理  (4)  缓存  (5)  多级别取消请求  (6)  和Activity和生命周期的联动(Activity结束时同时取消所有网络请求

hyl963254113的专栏 2119

ArcGIS符号库下载 | 制图规范、三调、1:1万地形图、土地利用总体规划图.....

最近整理了一些符号库 涉及的类型比较多 包含有三调的(二调的也加上去了),一些点线面符号库,1:1万地形图,1:5万土地利用,土地利用总体规划图

qq_43173805的博客 2万+

模板 - 树上问题(树的直径、动态查询树的直径、树的重心)

整理的算法模板合集: ACM模板 目录一、树的直径树形DP两次DFS / BFS(找到直径的两个端点)二、动态修改树的边权并求每个时刻的直径(线段树)三、树的重心 一、树的直径 树的直径满足如下性质: 若有多条直径,则所有的直径之间皆有公共点。 直径的两端一定是叶子。 树中距离某一直径端点最远的点,至少有一个是该直径的另一个端点。 对于树上任意一个点,与之距离最远的一个点,至少有一个直径的端点。 给你一个无权无向的树。编写程序以输出该树中最长路径(从一个节点到另一个节点)的长度。在这

繁凡さん的博客 1676

Android开源框架(整理)

*一个零基础的新人,我认为坚持是最最重要的。**我的很多朋友都找我来学习过,我也很用心的教他们,可是不到一个月就坚持不下来了。我认为他们坚持不下来有两点主要原因:他们打算入行不是因为兴趣,而是因为所谓的IT行业工资高,或者说完全对未来没有任何规划。刚开始学的时候确实很枯燥,这确实对你是个考验,所以说坚持下来也很不容易,但是如果你有兴趣就不会认为这是累,不会认为这很枯燥,总之还是贵在坚持。技术提升遇到瓶颈了?缺高级Android进阶视频学习提升自己吗?还有大量大厂面试题为你面试做准备!

2401_84010836的博客 933

docker容器ubuntu:latest里使用uv add mysqlclient安装失败的解决方案

在Docker容器(ubuntu:latest)中安装mysqlclient失败,原因是缺少必要的依赖包。错误显示系统找不到pkg-config工具和MySQL客户端库。解决方法:先更新软件源并安装构建工具、Python开发包、MySQL客户端库和pkg-config工具。具体步骤:运行sudo apt update,然后安装build-essential python3-dev default-libmysqlclient-dev pkg-config,最后再执行uv add mysqlclient即可成

拥抱具身智能,昇腾Ascend C 294

OkHttp拦截器之获取Response.body的内容

OkHttp拦截器之获取Response.body的内容项目中,由于使用了cookie,约定的有效期是20分钟,所以有可以会遇到cookie失效,无权操作,需要再次登录的情况。 在每个地方都进行无权操作error的处理显得不现实,于是就想到了使用拦截器。 但是当使用拦截器获取Response.body.string()后,后面的操作就直接返回Failed了,估计是因为流只能被使用一次的原因。

朱豪凯的博客 5万+

第47节:cesium 热力图效果(含源码+视频)

cesium 热力图效果

qq_29384639的博客 1675

Python爬虫实战教程:如何高效爬取税务局通知通告

税务局发布的通知通告包含政策法规、办税指南、公告信息等,是纳税人、企业合规经营的重要参考。官网发布频率高,手动查看不便,自动爬取并保存,方便信息及时掌握及历史数据归档。本文以合法合规的方式示范,建议实际应用前确认目标网站允许爬取的范围和方式。建议使用pandas进行数据清洗,如去重、空值处理等。对于研究税务政策、进行大数据分析、搭建行业信息平台,爬取税务局通知通告信息尤为关键。公告列表以分页形式展现,包含标题、发布时间和详情页链接。进行政策趋势图、发布频率统计等可视化。爬取公开数据时,务必遵守网站的。

2201_76125261的博客 1780

okhttp之RequestBody

Okhttp里面RequestBody是一个抽象类 抽象方法有: 1)public abstract @Nullable MediaType contentType(); 2)public abstract void writeTo(BufferedSink sink) throws IOException; 非抽象方法: 1) public long contentLeng...

yihuangol的博客 8016

泰凌微8258入门教程 基础篇①——Bluetooth® SIG Mesh 快速上手

Bluetooth® SIG Mesh Quick Start

6729

Android OkHttp框架全解析

在 Android 客户端开发中,网络请求是核心能力之一。从早期的到如今的 OkHttp,网络框架的演进始终围绕「简洁、高效、稳定」展开。OkHttp 作为 Square 公司开源的轻量级网络框架,不仅成为 Android 官方推荐的网络请求方案,更是 Retrofit、Volley、Glide 等框架的底层依赖。

. 1009

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

探索Android开源框架之OkHttp源码解析

一、OkHttp介绍 1.这个库的作用: 网络底层库,它是基于 http 协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟 HttpClient, HttpUrlConnection 的职责是一样的。其中封装了网络请求 get、post 等底层操作的实现。 2.项目中使用这个库的原因(优点) OkHttp 提供了对最新的 HTTP 协议版本 HTTP/2 和 SPDY的支持,这使得对同一个主机发出的所有请求都可以共享相同的套接字连接。 如果 HTTP/2 和 SPDY 不可用,

zhireshini233的博客 325

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Android 主流开源框架(三)OkHttp 源码解析

文章首发于我的个人博客:wildma的博客,这里有更好的阅读体验,欢迎关注。 前言 最近有个想法——就是把 Android 主流开源框架进行深入分析,然后写成一系列文章,包括该框架的详细使用与源码解析。目的是通过鉴赏大神的源码来了解框架底层的原理,也就是做到不仅要知其然,还要知其所以然。 这里我说下自己阅读源码的经验,我一般都是按照平时使用某个框架或者某个系统源码的使用流程入手的,首先要知道怎...

wildma的博客 1002

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Android 开源网络框架OKHttp4 Kotlin版本源码解析

文章目录1.Http2.0协议主要增加的优化点:2.OkHttp支持的内容3.OkHttp的使用流程4.OkHttp请求过程源码解析4.1.创建一个newCall 对象4.2.newCall执行同步或者异步请求,异步请求的主线流程4.3.Dispatcher的enqueue方法4.4.promoteAndExecute方法4.5.executeOn方法4.6.RealCall的run方法4.7.getResponseWithInterceptorChain方法4.8.同步的情况就比较简单了,execute方

风的轨迹 729

OKHttp开源框架学习一:同步请求总结

目录 系列文章: 版本: OkHttp同步方法总结: OkHttp异步方法总结: 同步和异步区别: 同步请求流程分析: 第一步,创建一个OkHttpClient对象 第二步,创建携带请求信息的Request对象 第三步,创建Call对象 第四步,call.execute() 系列文章: OKHttp开源框架学习一:同步请求总结 OKHttp开源框架学习二:异步请求总结 ...

songzi1228的博客 739

常用的 14 个开源框架

顶级程序员常用的 14 个开源框架,YYDS! 昨天下载下来Java16尝尝鲜。一看,好家伙,足足有176MB大。即使把jmc和jvisualvm给搞了出去,依然还是这么大,真的是让人震惊不已。 但即使JDK足够庞大,它的功能也已经不够用了。我们需要借助于第三方库,来完成企业级开发。比如,一个常见的SpringBoot服务,上百兆是轻轻松松的。 在这里,我盘点一下项目中常用的工具类库和Jar包,来看一看一个Java程序员要学多少东西才能走的更加长远。 1. Netty 第一送给Netty。其实我是有私心的,

qq794554587的博客 8444

三种网络请求开源框架:Volley、Okhttp、Retrofit

网络请求框架千千万,我选择Retrofit

Alpinist Wang 1395

OKHttp开源框架学习五:拦截器之RetryAndFollowUpInterceptor

目录 系列文章: 相关文章: RetryAndFollowUpInterceptor:重试重定向拦截器 RetryAndFollowUpInterceptor.intercept RetryAndFollowUpInterceptor作用: 系列文章: OKHttp开源框架学习一:同步请求总结 OKHttp开源框架学习二:异步请求总结 OKHttp开源框架学习三:任务调度核心类D...

songzi1228的博客 470
上一篇: 作为过来人,对于Android MVP模式的一些详解
下一篇: 阿里二面:关于 Retrofit 你知道多少?
初壹十五a
博客等级 码龄8年 146粉丝 257原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值