@@ -2,16 +2,16 @@ Upgrading to OkHttp 4
22=====================
33
44OkHttp 4.x upgrades our implementation language from Java to Kotlin and keeps everything else the
5- same. We' ve chosen Kotlin because it gives us powerful new capabilities while integrating closely
5+ same. We’ ve chosen Kotlin because it gives us powerful new capabilities while integrating closely
66with Java.
77
8- We spent a lot of time and energy on retaining strict compatibility with OkHttp 3.x. We' re even
8+ We spent a lot of time and energy on retaining strict compatibility with OkHttp 3.x. We’ re even
99keeping the package name the same: ` okhttp3 ` !
1010
11- There are three kinds of compatibility we' re tracking:
11+ There are three kinds of compatibility we’ re tracking:
1212
1313 * ** Binary compatibility** is the ability to compile a program against OkHttp 3.x, and then to run
14- it against OkHttp 4.x. We' re using the excellent [ japicmp] [ japicmp ] library via its
14+ it against OkHttp 4.x. We’ re using the excellent [ japicmp] [ japicmp ] library via its
1515 [ Gradle plugin] [ japicmp_gradle ] to enforce binary compatibility.
1616
1717 * ** Java source compatibility** is the ability to upgrade Java uses of OkHttp 3.x to 4.x without
@@ -20,39 +20,41 @@ There are three kinds of compatibility we're tracking:
2020 * ** Kotlin source compatibility** is the ability to upgrade Kotlin uses of OkHttp 3.x to 4.x
2121 without changing ` .kt ` files.
2222
23- With one exception, OkHttp 4.x is both binary- and Java source-compatible with OkHttp 3.x. You can
24- use an OkHttp 4.x .jar file with applications or libraries built for OkHttp 3.x. (The exception?
25- ` OkHttpClient ` makes more things ` final ` .)
23+ With a few small exceptions (below), OkHttp 4.x is both binary- and Java source-compatible with
24+ OkHttp 3.x. You can use an OkHttp 4.x .jar file with applications or libraries built for OkHttp 3.x.
2625
2726OkHttp is ** not** source-compatible for Kotlin callers, but upgrading should be automatic thanks to
28- Kotlin' s powerful deprecation features. Most developers should be able to use IntelliJ' s _ Code
27+ Kotlin’ s powerful deprecation features. Most developers should be able to use IntelliJ’ s _ Code
2928Cleanup_ for a safe and fast upgrade.
3029
31- For example, when we upgraded Square's Kotlin and Java codebases to OkHttp 4.x we had these
32- problems:
33-
34- * Single Abstract Method (SAM) conversions required us to replace lambdas with objects for Kotlin
35- callers.
36-
37- * OkHttp 4.x's new ` RequestBody.create() ` overload conflicted with an overload in one of our
38- subclasses. The compiler caught this!
39-
40- We expect most projects to have similarly trivial problems with the upgrade, if any. This guide
41- walks through all of the changes and how to address them.
42-
4330
4431Backwards-Incompatible Changes
4532------------------------------
4633
34+ #### OkHttpClient final methods
35+
4736` OkHttpClient ` has 26 accessors like ` interceptors() ` and ` writeTimeoutMillis() ` that were non-final
4837in OkHttp 3.x and are final in 4.x. These were made non-final for use with mocking frameworks like
49- [ Mockito] [ mockito ] . We believe subtyping ` OkHttpClient ` is the wrong way to test with OkHttp.
38+ [ Mockito] [ mockito ] . We believe subtyping ` OkHttpClient ` is the wrong way to test with OkHttp. If
39+ you must, mock ` Call.Factory ` which is the interface that ` OkHttpClient ` implements.
40+
41+ #### Internal API changes
5042
5143The ` okhttp3.internal ` package is not a published API and we change it frequently without warning.
52- Depending on code in this package is bad and will cause you problems with any upgrade. But the 4.x
44+ Depending on code in this package is bad and will cause you problems with any upgrade! But the 4.x
5345will be particularly painful to naughty developers that import from this package! We changed a lot
5446to take advantage of sweet Kotlin features.
5547
48+ #### Credentials.basic()
49+
50+ The username and password parameters to ` Credentials.basic() ` are now non-null strings. In OkHttp
51+ 3.x, null would yield a username or password of "null".
52+
53+ #### HttpUrl.queryParameterValues()
54+
55+ The return type of ` HttpUrl.queryParameterValues() ` is ` List<String?> ` . Lists that may contain null
56+ are uncommon and Kotlin callers may have incorrectly assigned the result to ` List<String> ` .
57+
5658
5759Code Cleanup
5860------------
@@ -61,63 +63,15 @@ IntelliJ and Android Studio offer a **Code Cleanup** feature that will automatic
6163deprecated APIs with their replacements. Access this feature from the _ Search Anywhere_ dialog
6264(double-press shift) or under the _ Analyze_ menu.
6365
64- The deprecation replacements that Code Cleanup possible are included in OkHttp 4.0. We will remove
65- them in a future update to OkHttp, so if you' re skipping releases you should upgrade to OkHttp 4.0
66+ We’ve included deprecated APIs in OkHttp 4.0 because they make migration easy. We will remove them
67+ in a future release! If you’ re skipping releases, it’ll be much easier if you upgrade to OkHttp 4.0
6668as an intermediate step.
6769
70+ #### Vars and Vals
6871
69- SAM Conversions
70- ---------------
71-
72- When you use Java APIs from Kotlin you can operate on Java interfaces as if they were Kotlin
73- lambdas. The [ feature] [ kotlin_sam ] is available for interfaces that define a Single Abstract Method
74- (SAM).
75-
76- But when you use Kotlin APIs from Kotlin there's no automatic conversion. Code that used SAM lambdas
77- with OkHttp 3.x: must use ` object : ` with OkHttp 4.x:
78-
79- Kotlin calling OkHttp 3.x:
80-
81- ``` kotlin
82- val client = OkHttpClient .Builder ()
83- .dns { hostname -> InetAddress .getAllByName(hostname).toList() }
84- .build()
85- ```
86-
87- Kotlin calling OkHttp 4.x:
88-
89- ``` kotlin
90- val client = OkHttpClient .Builder ()
91- .dns(object : Dns {
92- override fun lookup (hostname : String ) =
93- InetAddress .getAllByName(hostname).toList()
94- })
95- .build()
96- ```
97-
98- SAM conversion impacts these APIs:
99-
100- * Authenticator
101- * Dispatcher.setIdleCallback(Runnable)
102- * Dns
103- * EventListener.Factory
104- * HttpLoggingInterceptor.Logger
105- * LoggingEventListener.Factory
106- * OkHttpClient.Builder.hostnameVerifier(HostnameVerifier)
107-
108- JetBrains [ is working on] [ kotlin_sams ] SAM conversions of Kotlin interfaces. Expect it in a future
109- release of the Kotlin language.
110-
111-
112- Vars and Vals
113- -------------
114-
115- Java doesn't have language support for properties so developers make do with getters and setters.
72+ Java doesn’t have language support for properties so developers make do with getters and setters.
11673Kotlin does have properties and we take advantage of them in OkHttp.
11774
118- We recommend using _ Code Cleanup_ to fix these; it'll use ` @Deprecated ` to find replacements and fix
119- them automatically.
120-
12175 * ** Address** : certificatePinner, connectionSpecs, dns, hostnameVerifier, protocols, proxy,
12276 proxyAuthenticator, proxySelector, socketFactory, sslSocketFactory, url
12377 * ** Cache** : directory
@@ -155,11 +109,14 @@ them automatically.
155109 * ** Route** : address, proxy, socketAddress
156110 * ** TlsVersion** : javaName
157111
112+ #### Renamed Functions
113+
114+ * ** Headers.of()** : for symmetry with ` listOf() ` , ` setOf() ` , etc., we’ve replaced
115+ ` Headers.of(String...) ` with ` headersOf(vararg String) ` .
158116
159- Extension Functions
160- -------------------
117+ #### Extension Functions
161118
162- _ Code Cleanup _ will fix these too:
119+ We’ve migrated from static functions to extension functions where we think they fit.
163120
164121| Java | Kotlin |
165122| :---------------------------------- | :------------------------------ |
@@ -183,24 +140,47 @@ _Code Cleanup_ will fix these too:
183140| ResponseBody.create(String) | String.toResponseBody() |
184141
185142
186- headersOf()
187- -----------
143+ SAM Conversions
144+ ---------------
188145
189- For symmetry with ` listOf() ` , ` setOf() ` , etc., we've replaced ` Headers.of(String...) ` with
190- ` headersOf(vararg String) ` .
146+ When you use Java APIs from Kotlin you can operate on Java interfaces as if they were Kotlin
147+ lambdas. The [ feature] [ java_sams ] is available for interfaces that define a Single Abstract Method
148+ (SAM).
149+
150+ But when you use Kotlin APIs from Kotlin there’s no automatic conversion. Code that used SAM lambdas
151+ with OkHttp 3.x: must use ` object : ` with OkHttp 4.x:
152+
153+ Kotlin calling OkHttp 3.x:
154+
155+ ``` kotlin
156+ val client = OkHttpClient .Builder ()
157+ .dns { hostname -> InetAddress .getAllByName(hostname).toList() }
158+ .build()
159+ ```
191160
161+ Kotlin calling OkHttp 4.x:
192162
193- queryParameterValues()
194- ----------------------
163+ ``` kotlin
164+ val client = OkHttpClient .Builder ()
165+ .dns(object : Dns {
166+ override fun lookup (hostname : String ) =
167+ InetAddress .getAllByName(hostname).toList()
168+ })
169+ .build()
170+ ```
195171
196- The return type of ` HttpUrl.queryParameterValues() ` is ` List<String?> ` . Lists that may contain
197- null are uncommon and Kotlin callers may have incorrectly assigned the result to ` List<String> ` .
172+ SAM conversion impacts these APIs:
198173
174+ * Authenticator
175+ * Dispatcher.setIdleCallback(Runnable)
176+ * Dns
177+ * EventListener.Factory
178+ * HttpLoggingInterceptor.Logger
179+ * LoggingEventListener.Factory
180+ * OkHttpClient.Builder.hostnameVerifier(HostnameVerifier)
199181
200- [ japicmp ] : https://github.com/siom79/japicmp
201- [ japicmp_gradle ] : https://github.com/melix/japicmp-gradle-plugin
202- [ mockito ] : https://site.mockito.org/
203- [ kotlin_sam ] : https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
182+ JetBrains [ is working on] [ kotlin_sams ] SAM conversions of Kotlin interfaces. Expect it in a future
183+ release of the Kotlin language.
204184
205185
206186Companion Imports
@@ -230,6 +210,16 @@ sed -i "" \
230210```
231211
232212
213+ Advanced Profiling
214+ ------------------
215+
216+ Android Studio’s Advanced Profiling feature rewrites OkHttp bytecode for instrumentation.
217+ Unfortunately it crashes on OkHttp 4.x’s bytecode. Until [ Google’s bug] [ advanced_profiling_bug ] is
218+ fixed you must disable advanced profiling in Android Studio.
219+
220+ ![ Disable Advanced Profiling
] ( images/[email protected] ) 221+
222+
233223R8 / ProGuard
234224-------------
235225
@@ -238,11 +228,16 @@ R8 and ProGuard are both code optimizers for `.class` files.
238228R8 is the [ default optimizer] [ r8 ] in Android Studio 3.4 and newer. It works well with all
239229releases of OkHttp.
240230
241- ProGuard was the previous default. We' re [ tracking problems] [ proguard_problems ] with interactions
242- between ProGuard, OkHttp 4.x, and Kotlin-originated ` .class ` files. Make sure you' re on the latest
243- release if you' re using ProGuard,
231+ ProGuard was the previous default. We’ re [ tracking problems] [ proguard_problems ] with interactions
232+ between ProGuard, OkHttp 4.x, and Kotlin-originated ` .class ` files. Make sure you’ re on the latest
233+ release if you’ re using ProGuard,
244234
245235
246- [ kotlin_sams ] : https://discuss.kotlinlang.org/t/new-type-inference-in-kotlin-1-3-0-rc-190/9914/2
236+ [ advanced_profiling_bug ] : https://issuetracker.google.com/issues/135141615
237+ [ japicmp ] : https://github.com/siom79/japicmp
238+ [ japicmp_gradle ] : https://github.com/melix/japicmp-gradle-plugin
239+ [ java_sams ] : https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
240+ [ kotlin_sams ] : https://youtrack.jetbrains.com/issue/KT-11129
241+ [ mockito ] : https://site.mockito.org/
247242 [ proguard_problems ] : https://github.com/square/okhttp/issues/5167
248243 [ r8 ] : https://developer.android.com/studio/releases#r8-default
0 commit comments