Android Okhttp BUG

2,105 阅读2分钟

Log异常信息 :

W/System.err: java.io.IOException: unexpected end of stream on http://xxx.xxx.cn/...
W/System.err:     at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.kt:204)
W/System.err:     at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:110)
W/System.err:     at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:93)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:222)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
W/System.err:     at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err:     at java.lang.Thread.run(Thread.java:923)
W/System.err: Caused by: java.io.EOFException: \n not found: limit=0 content=…
W/System.err:     at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.kt:332)
W/System.err:     at okhttp3.internal.http1.HeadersReader.readLine(HeadersReader.kt:29)
W/System.err:     at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.kt:180)
W/System.err: 	... 18 more

问题总结 :

  1. java.io.IOException: unexpected end of stream on http://xxx.xxx.cn/...
  2. Caused by: java.io.EOFException: \n not found: limit=0 content=…
  3. java.net.ProtocolException: unexpected end of stream

出现原因: Android模拟器没有用到Windowshosts文件配置, 导致程序跑到手机上无法访问内网的地址

🌴测试环境为 : Android11 API 30

解决方式: 给Android配置Windowshosts文件

一、启动模拟器时指定DNS服务器
.\emulator.exe -avd 模拟器名称 -writable-system -no-snapshot -dns-server 192.0.x.x,192.0.x.x

如果该方式失败, 可以再尝试修改hosts即方式二。

二、使用主机文件

Android模拟器不会使用Windows的本地主机文件。需要在Android模拟器映像本身上编辑hosts文件。

  1. 启动Android虚拟设备 (AVD) :
  2. 打开emulator.exe所在路径 C:\XXX\android-sdk\emulator

    .\emulator.exe -list-avds
    .\emulator.exe -avd 模拟器名称 -writable-system -no-snapshot
    
    -no-snapshot-load	执行冷启动,并在退出时保存模拟器状态。
    -no-snapshot-save	如果可能,执行快速启动,但在退出时不保存模拟器状态。
    -no-snapshot	        彻底停用快速启动功能 - 它不会加载或保存模拟器状态。
    

    启动后不要关闭窗口

  3. 重新挂载设备映像为可写的 (writable) :
  4. adb root
    adb disable-verity
    adb remount
    adb reboot
    
    adb shell
    mount -o rw,remount /system
    

    Android Studio自带的模拟器很容易卡死在了adb reboot导致失败..., 强烈建议使用Genymotion模拟器。

  5. 将Android hosts文件的副本保存到Windows主机上的临时位置 :
  6. adb pull /system/etc/hosts D:\TempFiles

  7. 编辑Android hosts,添加指向主机的条目:
  8. 127.0.0.1     localhost  
    10.0.2.2      mytesthost  
    

  9. 将编辑好的hosts文件保存回Android模拟器中:
  10. adb push D:\TempFiles\hosts /system/etc  
    

  11. 测试Android模拟器是否可以访问到该主机:
  12. adb shell
    adb ping mytesthost
    

    🌴测试通过后Okhttp不会再出现unexpected end of stream on http://xxx.xxx.cn/... 或者 EOFException: \n not found: limit=0 content=…异常了。

🍎 OkHttp上相关的issue也很多:

github.com/square/okht…

参考

从命令行启动模拟器 developer.android.com/studio/run/…

web.archive.org/web/2018061…

stackoverflow.com/questions/3…

Read-only file system blog.csdn.net/wlwh90/arti…