前言:17年做过一个支付sdk开发,那会年轻,天不怕地不怕,手写HttpUrlConnection,实在惭愧。
转眼六年过去了,公司给安排一个新的项目需求,依然是做一个sdk,好吧,开干!
写项目最大的问题就是网络访问了,一套mvvm,携程+flow+retrofit+okhttp吧啦吧啦!
正常项目没问题,sdk肯定是不行的,sdk开发尽量做到小,尽量不引用三方依赖,尽量不造成依赖冲突,那mvvm一套框架肯定是用不了了,必须涉及网络访问,那好歹保留okhttp吧!
反编译了竞品的sdk,发现他们居然也是手写HttpUrlConnection,看到了自己当年的影子!
那还是自己辛苦一点,把okhttp的源码拷贝下来放到项目里,不用依赖的方式(相当于自己写了一个网络框架)。
废话结束,开工:
还好Android是开源的,要拷贝,先从github上下载源码:
GitHub - square/okhttp: Square’s meticulous HTTP client for the JVM, Android, and GraalVM.GitHub - square/okhttp: Square’s meticulous HTTP client for the JVM, Android, and GraalVM.GitHub - square/okhttp: Square’s meticulous HTTP client for the JVM, Android, and GraalVM.
另外okhttp内部依赖okio,把okio也下载下来:
GitHub - square/okio: A modern I/O library for Android, Java, and Kotlin Multiplatform.
下载下来后自己傻兮兮的直接用AS打开,还试图去解决build问题,后来仔细看项目结构,换IntelliJ,依然出现各种问题,build失败。
自此第一大难题出现:源码打不开
没办法,用笨办法,新建一个Android Stuido项目,implementation的方式引入okhttp,然后找到缓存本地的jar包,解压出class文件,用jad转成java文件,兴冲冲的以为可以直接用,结果呵呵,kt发展这么多年了,源码早就用kotlin写了,再用AS把java转成kt。
嗯,转完了依然build失败,里面问题太多,这条路失败(不过很接近了)
再换一条路,把github上的源码,其中Android部分拷贝过来。结果是也失败了,缺少很多文件,这条路虽然失败了,但是我发现了一个很重要的东西:源码适配了很多平台,有些函数在不同的平台有不同的实现(actual关键字)
偶然间,我用Android stuido读okhttp源码的时候,我发现文件的后缀名是.kt,岂不是说as帮我把class文件转成了kt,至少as肯定有这个功能:
而且Android的jar,函数的实现体也是针对Android的,并且没有把其他平台的代码打包进去
聪明的做法是找到这个工具,反编译okhttp的jar,就大功告成了。但是我比较笨,没找到这个工具。
于是我把项目切换到project目录,找到okhttp.jar里面的类:
新建一个项目,新建okhttp3文件夹,在这个文件夹里面新建的同名kt文件,一个一个把类的代码拷贝进去。
但是as并不能把所有的class都反编译成kt,比如这个Util.class其实是很重要的类
我先避开这些class,先把已经转成kt的先拷贝进去(这里花费了一个小时)
然后删掉actual关键字,去掉所有@IgnoreJRERequirement注解(看名字就知道是用来忽视什么),
再然后就是剩下的报错了,一个一个来:
第一个问题:函数引用问题,举个例子:
RequestBody类里有个checkOffsetAndCount方法引用报红。
这时候从jar项目里找到RequestBody,搜索checkOffsetAndCount,然后点进去,神奇的事情发生了,as打开了一个Util.kt:
还记得上面的Util.class吗,里面都有checkOffsetAndCount方法,kt里有具体实现,赶紧在新建的项目里,同路径下新建一个Util.kt,把有实现的代码拷贝进去,RequestBody里的checkOffsetAndCount报红消失!
同理,jar里所有的class文件都找到了对应的kt实现类。
第二个问题:拓展函数问题,举个例子:
这个substring,必须有开始和结束坐标,有的地方只有end,有的地方根本begin,end都没有:
没办法,只能自己去加上。
第三个问题:删除多余的平台
OpenJSSE,BouncyCastle,Conscrypt这三个平台下,有类找不到:
这三个平台的支持类直接删掉,Android适配器里面的引用也删掉了
另外,对接sdk的项目有可能已经依赖了okhttp,或者说如果引入leakcanary,leakcanary内部也是依赖okio的,就会出现依赖重复问题。
这个问题的解决办法:修改okhttp和okio的包名(记得混淆文件里也需要修改)
至此copy过来的源码问题都解决了(可能有遗忘的,可以留言,我尽量帮忙)
最后附上全部demo:
Android Studio版本:Flamingo|2022.2.1
Gradle:gradle-8.0-bin.zip
https://github.com/EnvyChenchen/sdkhttp
下载后把okhttp3和okio两个文件夹复制到你项目的\app\src\main\java\目录下
就可以开心的去掉 implementation("com.squareup.okhttp3:okhttp:***")
PS:gson我也提取下来了,gson地址:
不过gson下载下来后把/src/main/java/com/google/gson文件夹下的内容直接复制过去直接就能用,就不放项目代码了,自己尝试就行
若有侵权,请联系我,立马删除,谢谢! 若有侵权,请联系我,立马删除,谢谢! 若有侵权,请联系我,立马删除,谢谢! qq:307488756