网络移动开发【免费下载链接】okhttputils[停止维护]okhttp的辅助类项目地址https://gitcode.com/gh_mirrors/ok/okhttputils点击查看免费下载本文是一份围绕开源仓库 okhttputils 的完整使用指南。okhttputils 是一套对 Square OkHttp 的辅助封装类当前对应 OkHttp 版本3.3.1覆盖 GET/POST、表单上传、文件下载、进度回调、自定义 Callback、Session 保持、自签名 HTTPS 等日常高频需求。读完本文你将掌握如何引入该库、在 Application 中配置 OkHttpClient、使用链式 API 发起各类请求、定制回调与拦截器以及如何利用 tag 机制统一取消请求并配置混淆规则。说明该项目作者因个人原因已停止维护仓库状态为停止维护本文所有结论均以当前仓库代码与 README 为准用于学习封装思想与历史实现生产环境引入请自行评估。1. 项目概览与能力清单okhttputils 的核心入口是 OkHttpUtils.java它对外提供一套静态工厂方法与统一的请求执行入口。根据 README.md 与源码结构该库目前对以下需求进行了封装一般的 GET 请求一般的 POST 请求表单形式基于 Http Post 的文件上传类似表单支持单文件与多文件文件下载 / 加载图片上传、下载的进度回调支持取消某个请求按单个 call 或按 tag 统一取消支持自定义 Callback支持 HEAD、DELETE、PATCH、PUT支持 Session 的保持Cookie 持久化支持自签名网站 HTTPS 的访问提供方法设置证书即可从源码结构看库内部分工清晰builder/目录存放各类请求的 Builder如 GetBuilder.java、PostFormBuilder.java、PostStringBuilder.java、PostFileBuilder.java、OtherRequestBuilder.javarequest/目录存放与 Builder 一一对应的请求实现如 GetRequest.java、PostFormRequest.java 等callback/目录存放回调基类与内置回调实现cookie/目录存放 CookieJar 实现与多种 Cookie 存储策略https/、log/、utils/分别提供 HTTPS 工具、日志拦截器与平台工具类。2. 引入方式2.1 Android StudioGradle在模块的build.gradle中添加依赖compile com.zhy:okhttputils:2.6.2注意当前仓库使用的还是compile关键字对应旧版 Android Gradle 插件使用新版 AGP 时应替换为implementation并在repositories中确保可访问 Maven 中央仓库。2.2 Eclipse下载仓库根目录下提供的 jar 包okhttputils-2_6_2.jar导入工程后需要同时导入 okhttp 与 okio 的 jar下载自 OkHttp 官方发布页当前对应版本为 okhttp 3.3.1。3. 配置 OkHttpClientinitClient 全局初始化默认情况下框架直接使用 OkHttp 的默认配置生成OkHttpClient。任何需要自定义配置的场景都要在Application中调用OkHttpUtils.initClient(okHttpClient)进行设置示例代码如下摘自 READMEpublic class MyApplication extends Application { Override public void onCreate() { super.onCreate(); OkHttpClient okHttpClient new OkHttpClient.Builder() // .addInterceptor(new LoggerInterceptor(TAG)) .connectTimeout(10000L, TimeUnit.MILLISECONDS) .readTimeout(10000L, TimeUnit.MILLISECONDS) //其他配置 .build(); OkHttpUtils.initClient(okHttpClient); } }别忘了在AndroidManifest.xml中注册该 Application。从 OkHttpUtils.java 的源码可以看出initClient的细节单例采用双重检查锁DCL保证线程安全volatile static OkHttpUtils mInstance传入的okHttpClient为null时内部会new OkHttpClient()兜底OkHttpUtils.getInstance()本质上就是initClient(null)即拿默认客户端。3.1 请求级别的超时覆盖除了全局配置RequestCall还支持对单次请求单独设置超时。链式调用build()之后可以追加OkHttpUtils.get()// .url(url)// .build()// .connTimeOut(20000) .readTimeOut(20000) .writeTimeOut(20000) .execute(callback);查看 RequestCall.java 的实现只要readTimeOut、writeTimeOut、connTimeOut任一大于 0就会基于全局客户端调用newBuilder()克隆一份并重设三个超时未指定的超时统一回落为OkHttpUtils.DEFAULT_MILLISECONDS即 10 秒否则直接使用全局客户端创建 Call。这一设计让全局默认 局部特例两种场景都能覆盖。4. Cookie 与 Session 保持Cookie 的配置同样通过 OkHttpClient 的cookieJar方法完成参考上面的配置过程CookieJarImpl cookieJar new CookieJarImpl(new PersistentCookieStore(getApplicationContext())); OkHttpClient okHttpClient new OkHttpClient.Builder() .cookieJar(cookieJar) //其他配置 .build(); OkHttpUtils.initClient(okHttpClient);项目中内置了以下实现位于cookie/store包下PersistentCookieStore持久化 Cookie序列化后存入 SharedPreferencesApp 重启后仍可恢复 SessionSerializableHttpCookie可序列化的Cookie包装类供持久化存储使用MemoryCookieStoreCookie 信息仅保存在内存中进程结束后丢失。如果遇到问题可以自行实现CookieJar接口编写 Cookie 管理代码对于持久化 Cookie也可选用第三方 PersistentCookieJarfranmontiel/PersistentCookieJar。框架本身只提供几个实现类你可以自行定制或替换。4.1 源码层面的实现细节CookieJarImpl.java 实现了 OkHttp 的CookieJar接口构造参数为null时会通过Exceptions.illegalArgument抛出参数异常saveFromResponse与loadForRequest均声明为synchronized以保证并发安全。PersistentCookieStore.java 使用SharedPreferences文件名为CookiePrefsFile持久化Cookie 经SerializableHttpCookie包装后通过 Java 序列化再转十六进制字符串保存读取时会检查cookie.expiresAt() System.currentTimeMillis()来判断过期并自动清理。MemoryCookieStore.java 则以HashMapString, ListCookie按 host 维度存放新写入的 Cookie 会覆盖同名旧 Cookie。示例工程 MainActivity.java 中还演示了如何清空 Session通过OkHttpUtils.getInstance().getOkHttpClient().cookieJar()取出 CookieJar若为CookieJarImpl实例则调用getCookieStore().removeAll()。5. Log 日志输出初始化 OkHttpClient 时通过设置拦截器实现日志打印。框架提供了一个LoggerInterceptor你也可以自行实现InterceptorOkHttpClient okHttpClient new OkHttpClient.Builder() .addInterceptor(new LoggerInterceptor(TAG)) //其他配置 .build(); OkHttpUtils.initClient(okHttpClient);查看 LoggerInterceptor.java 的实现它提供两个构造方法LoggerInterceptor(String tag)等价于LoggerInterceptor(tag, false)默认不打印响应体LoggerInterceptor(String tag, boolean showResponse)showResponse为true时额外打印响应正文。拦截器在intercept()中先打印请求信息method、url、headers、requestBody 的 contentType 与文本内容再调用chain.proceed(request)随后打印响应信息url、code、protocol、message。对于 JSON、XML、HTML、text/*等文本类型的请求/响应体会输出正文而文件等二进制内容会输出maybe [file part] , too large too print , ignored!提示并忽略避免大体积二进制内容刷屏。注意打印响应体时它构造了一个 Response 克隆来读取避免破坏原始响应流。6. HTTPS 与自签名证书依然通过配置即可完成框架提供HttpsUtils工具类位于 HttpsUtils.java。6.1 设置可访问所有 HTTPS 网站信任所有证书HttpsUtils.SSLParams sslParams HttpsUtils.getSslSocketFactory(null, null, null); OkHttpClient okHttpClient new OkHttpClient.Builder() .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager) //其他配置 .build(); OkHttpUtils.initClient(okHttpClient);6.2 设置具体的服务器证书HttpsUtils.SSLParams sslParams HttpsUtils.getSslSocketFactory(证书的inputstream, null, null); OkHttpClient okHttpClient new OkHttpClient.Builder() .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager) //其他配置 .build(); OkHttpUtils.initClient(okHttpClient);6.3 双向认证客户端证书HttpsUtils.getSslSocketFactory( 证书的inputstream, // 服务器证书 本地证书的inputstream, // 本地客户端证书BKS 格式 本地证书的密码)同样的框架只是提供了实现类你可以自行实现SSLSocketFactory并传入sslSocketFactory。6.4 源码解析HttpsUtils.getSslSocketFactory(InputStream[] certificates, InputStream bksFile, String password)的内部逻辑见 HttpsUtils.java传入了certificates时通过CertificateFactory逐个解析 X.509 证书并装入 KeyStore再交给TrustManagerFactory生成信任管理器最终包装为MyTrustManager——它优先用系统默认信任链校验失败时再尝试本地证书相当于系统信任 自签名证书双保险未传入证书时使用UnSafeTrustManagercheckServerTrusted不做任何校验即信任所有服务器传入bksFile与password时以BKS格式加载客户端 KeyStore 并初始化KeyManagerFactory用于双向认证。示例工程 MyApplication.java 中同时配置了 LoggerInterceptor、PersistentCookieJar、HostnameVerifier恒返回 true以及getSslSocketFactory(null, null, null)生成的 SSLSocketFactory是一份完整的httphttpscookielog组合配置样板仓库sample-okhttp/src/main/assets/下也提供了srca.cer、zhy_client.bks、zhy_server.cer三份测试证书资源。7. 核心用法示例以下示例均摘自 README并可在 sample-okhttp 工程中找到对应代码。7.1 GET 请求String url http://www.csdn.net/; OkHttpUtils .get() .url(url) .addParams(username, hyman) .addParams(password, 123) .build() .execute(new StringCallback() { Override public void onError(Request request, Exception e) { } Override public void onResponse(String response) { } });GET 参数在 GetBuilder.java 的appendParams中通过android.net.Uri拼接到 URL 查询串build()后由 GetRequest.java 生成builder.get()请求其buildRequestBody()返回null。7.2 POST 请求表单形式OkHttpUtils .post() .url(url) .addParams(username, hyman) .addParams(password, 123) .build() .execute(callback);7.3 Post JSON字符串请求体OkHttpUtils .postString() .url(url) .content(new Gson().toJson(new User(zhy, 123))) .mediaType(MediaType.parse(application/json; charsetutf-8)) .build() .execute(new MyStringCallback());向服务器提交一个 Gson 字符串。注意传递 JSON 时不要通过addHeader去设置Content-Type而应使用.mediaType(MediaType.parse(application/json; charsetutf-8))。查看 PostStringRequest.java若未显式指定mediaType默认使用text/plain;charsetutf-8content为空会抛出参数异常。7.4 Post File文件作为请求体OkHttpUtils .postFile() .url(url) .file(file) .build() .execute(new MyStringCallback());将文件直接作为请求体发送到服务器。PostFileRequest.java 中file为空会抛异常mediaType未指定时默认为application/octet-stream。7.5 Post 表单形式上传文件支持多文件OkHttpUtils.post()// .addFile(mFile, messenger_01.png, file)// .addFile(mFile, test1.txt, file2)// .url(url) .params(params)// .headers(headers)// .build()// .execute(new MyStringCallback());支持单个与多个文件addFile的第一个参数为文件的 key即类别表单中input typefile namemFile/的name属性。PostFormBuilder.java 通过files(String key, MapString, File)与addFile(String name, String filename, File file)收集文件底层 PostFormRequest.java 在无文件时构造FormBody在有文件时构造MultipartBodysetType(MultipartBody.FORM)普通参数以form-data; namekey的 Content-Disposition 加入文件的 MIME 类型通过URLConnection.getFileNameMap()按文件名猜测猜不到时回退为application/octet-stream。8. 自定义 Callback 与泛型解析目前内部包含StringCallback、FileCallBack、BitmapCallback三个内置回调全部继承自抽象基类 Callback.java。你可以根据自己的需求自定义 Callback例如希望回调User对象public abstract class UserCallback extends CallbackUser { Override public User parseNetworkResponse(Response response) throws IOException { String string response.body().string(); User user new Gson().fromJson(string, User.class); return user; } } OkHttpUtils .get()// .url(url)// .addParams(username, hyman)// .addParams(password, 123)// .build()// .execute(new UserCallback() { Override public void onError(Request request, Exception e) { mTv.setText(onError: e.getMessage()); } Override public void onResponse(User response) { mTv.setText(onResponse: response.username); } });8.1 Callback 基类的线程模型通过parseNetworkResponse回调的 Response 进行解析该方法运行在子线程OkHttp 的线程池中所以可以在里面执行任何耗时操作如response.body().string()、Gson 反序列化、文件读写。Callback.java 定义了完整回调生命周期onBefore(Request, int id)请求发送前回调运行在 UI 线程示例中用于设置 loading... 标题inProgress(float progress, long total, int id)进度回调progress 取值 0~1UI 线程parseNetworkResponse(Response, int id)抽象方法线程池线程执行返回解析后的泛型对象onError(Call, Exception, int id)失败回调UI 线程onResponse(T, int id)成功回调UI 线程onAfter(int id)请求结束回调无论成败都会执行示例中用于恢复标题validateReponse(Response, int id)默认response.isSuccessful()若你在parseNetworkResponse里自行处理了响应码应让该方法返回true。回调切换到 UI 线程的机制在 Platform.java 中Android 环境下通过Handler(Looper.getMainLooper())将回调 post 到主线程非 Android 环境则使用Executors.newCachedThreadPool()。失败/成功的分发入口见 OkHttpUtils.java其中execute(RequestCall, Callback)还会在回调前检查call.isCanceled()并默认通过validateReponse校验响应码最后在finally中关闭response.body()防止流泄漏。8.2 泛型回调GenericsCallback除了手写parseNetworkResponse框架还提供了更简洁的泛型回调 GenericsCallback.java配合 IGenericsSerializator.java 接口T T transform(String response, ClassT classOfT)使用。示例工程中的 JsonGenericsSerializator.java 即用 Gson 实现该接口OkHttpUtils .post()// .url(url)// .addParams(username, hyman)// .addParams(password, 123)// .build()// .execute(new GenericsCallbackUser(new JsonGenericsSerializator()) { Override public void onError(Call call, Exception e, int id) { mTv.setText(onError: e.getMessage()); } Override public void onResponse(User response, int id) { mTv.setText(onResponse: response.username); } });GenericsCallback通过反射获取泛型实参类型getGenericSuperclass()上的ParameterizedType若目标类型是String则直接返回响应文本否则交给IGenericsSerializator转换。示例工程同时提供了 UserCallback.java单个对象与 ListUserCallback.javaListUser两种手写回调作为对照。9. 下载文件与显示图片9.1 下载文件OkHttpUtils// .get()// .url(url)// .build()// .execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), gson-2.2.1.jar)// { Override public void inProgress(float progress) { mProgressBar.setProgress((int) (100 * progress)); } Override public void onError(Request request, Exception e) { Log.e(TAG, onError : e.getMessage()); } Override public void onResponse(File file) { Log.e(TAG, onResponse : file.getAbsolutePath()); } });下载文件使用FileCallBack需要传入文件保存的文件夹路径以及文件名。FileCallBack.java 的saveFile实现要点以 2048 字节缓冲区循环读取response.body().byteStream()并写入FileOutputStream目标目录不存在时自动mkdirs()每读取一段就通过OkHttpUtils.getInstance().getDelivery()把inProgress(finalSum * 1.0f / total, total, id)投递到 UI 线程实现下载进度条finally中关闭响应体与输入输出流。9.2 显示图片OkHttpUtils .get()// .url(url)// .build()// .execute(new BitmapCallback() { Override public void onError(Request request, Exception e) { mTv.setText(onError: e.getMessage()); } Override public void onResponse(Bitmap bitmap) { mImageView.setImageBitmap(bitmap); } });显示图片时传入BitmapCallback即可其内部 BitmapCallback.java 使用BitmapFactory.decodeStream(response.body().byteStream())完成解析。10. 上传与下载的进度显示new CallbackT() { //... Override public void inProgress(float progress) { //use progress: 0 ~ 1 } }Callback 回调中有inProgress方法直接复写即可progress 取值范围为 0 ~ 1。10.1 上传进度的底层实现上传进度依赖装饰器 CountingRequestBody.java它包装真实的RequestBody通过ForwardingSink在每次write时累计已写字节数并回调Listener.onRequestProgress(bytesWritten, contentLength)。PostFormRequest与PostFileRequest都在wrapRequestBody中见 PostFormRequest.java将进度值bytesWritten * 1.0f / contentLength投递到 UI 线程最终回调callback.inProgress(...)。也就是说上传与下载的进度回调统一在Callback.inProgress(float progress, long total, int id)中实现其中total为总字节数。11. HEAD、DELETE、PUT、PATCHOkHttpUtils .put()//also can use delete() ,head() , patch() .requestBody(RequestBody.create(null, may be something))// .build()// .execute(new MyStringCallback());如果需要 requestBody例如 PUT、PATCH自行构造并传入即可。OkHttpUtils.java 中put()、delete()、patch()分别返回携带METHOD.PUT、METHOD.DELETE、METHOD.PATCH的OtherRequestBuilderhead()返回HeadBuilder。底层 OtherRequest.java 的buildRequest按方法分发到builder.put/delete/head/patch其中delete在无 body 时走builder.delete()有 body 时走builder.delete(requestBody)若requestBody与content均为空且方法要求请求体HttpMethod.requiresRequestBody会抛出参数异常仅传字符串content时会自动包装为text/plain;charsetutf-8的 RequestBody。12. 同步请求Response response OkHttpUtils .get()// .url(url)// .tag(this)// .build()// .execute();execute方法不传入 callback 即为同步请求直接返回okhttp3.Response。见 RequestCall.java同步分支调用buildCall(null)后执行call.execute()。注意同步请求会阻塞调用线程不要在 Android 主线程直接调用。13. 取消请求13.1 取消单个请求RequestCall call OkHttpUtils.get().url(url).build(); call.cancel();13.2 根据 tag 取消请求目前对所有支持的方法都提供了最后一个参数Object tag取消则通过OkHttpUtils.cancelTag(tag)执行。例如在 Activity 中当 Activity 销毁时取消请求OkHttpUtils .get()// .url(url)// .tag(this)// .build()// Override protected void onDestroy() { super.onDestroy(); //可以取消同一个tag的 OkHttpUtils.cancelTag(this);//取消以Activity.this作为tag的请求 }比如当前 Activity 页面所有的请求都以 Activity 对象作为 tag就可以在onDestroy()里统一取消。cancelTag(Object tag) 的实现会遍历mOkHttpClient.dispatcher().queuedCalls()排队中与runningCalls()执行中两个队列凡是tag.equals(call.request().tag())的 Call 一律执行cancel()。RequestCall.cancel()则只取消自身持有的那个 Call。示例工程 MainActivity.java 的onDestroy()中正是用OkHttpUtils.getInstance().cancelTag(this)统一清理本页面请求。13.3 请求 IDidBuilder 基类 OkHttpRequestBuilder.java 还提供了.id(int)方法为请求设置标识所有回调方法都携带int id参数可在同一个 Callback 实例中根据 id 区分不同请求做不同处理示例工程中id(100)与id(101)分别代表 http 与 https 请求见 MainActivity.java。14. Proguard 混淆规则若工程开启混淆在 proguard 文件中加入以下规则#okhttputils -dontwarn com.zhy.http.** -keep class com.zhy.http.**{*;} #okhttp -dontwarn okhttp3.** -keep class okhttp3.**{*;} #okio -dontwarn okio.** -keep class okio.**{*;}仓库根目录下的 okhttputils/proguard-rules.pro 与 sample-okhttp/proguard-rules.pro 也包含了对应规则可直接参考。15. 示例工程快速上手仓库中的 sample-okhttp 模块是完整的可运行示例包含MyApplication.java完整的 OkHttpClient 初始化超时、LoggerInterceptor、CookieJar、HostnameVerifier、SSLSocketFactoryMainActivity.javaGET/POST、postString、postFile、表单多文件上传、下载文件、显示图片、HTTPS 访问、清空 Session、按 tag 取消请求等全部用例JsonGenericsSerializator.java、UserCallback.java、ListUserCallback.java三种回调定制方式的对照src/main/assets/下的srca.cer、zhy_client.bks、zhy_server.cerHTTPS 双向认证测试证书资源。将接口地址替换为本地服务即可逐项验证各功能。由于项目基于 OkHttp 3.3.1 构建若在更高版本 OkHttp 上复用代码需要注意sslSocketFactory(SSLSocketFactory, X509TrustManager)等 API 的签名差异。16. 小结okhttputils 的核心设计可以概括为Builder 链式构建 → OkHttpRequest 生成请求 → RequestCall 统一调度异步/同步/取消/单请求超时→ Callback 泛型回调子线程解析 主线程分发→ CountingRequestBody/FileCallBack 双向进度 → initClient 单例注入全局客户端。这套分层清晰的封装思路与提供实现类、也允许自行定制接口的开放态度对于理解 OkHttp 的 Call、Callback、Interceptor、CookieJar、SSLSocketFactory 等核心概念以及设计自己的网络层工具都具有很好的参考价值。本文全部代码与结论均可在当前仓库对应文件中找到原始出处可作为深入学习与二次开发时的对照索引。赞分享网络移动开发【免费下载链接】okhttputils[停止维护]okhttp的辅助类项目地址https://gitcode.com/gh_mirrors/ok/okhttputils点击查看免费下载相关推荐Android网络请求终极指南OKHttpUtils完整教程Android网络请求终极指南OKHttpUtils完整教程 OKHttpUtils是一款专为Android开发者打造的网络请求辅助类库基于OKHttp实现网络移动开发YTKNetwork 使用指南基于 AFNetworking 的高层 iOS 网络请求封装库YTKNetwork 使用指南基于 AFNetworking 的高层 iOS 网络请求封装库 本文围绕开源仓库 YTKNetwork 的官方中文说明文档 D开发工具maxvit_base_tf_512.in1k特征提取教程3行代码实现图像嵌入maxvit_base_tf_512.in1k特征提取教程3行代码实现图像嵌入 想要快速获取高质量的图像特征向量吗maxvit_base_tf_512.in创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考