91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android OkHttp, 一行代碼 OkHttp提升請求穩定性

發布時間:2020-09-04 16:10:25 來源:網絡 閱讀:366 作者:Android丶VG 欄目:移動開發

OkHttp是可以說是Android開發中,每個項目都必需依賴的網絡庫,我們可以很便捷高效的處理網絡請求,極大的提升了編碼效率。但是有時候,我們使用OkHttp也會遇到這樣的問題

一.崩潰的stacktrace

E AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
E AndroidRuntime: Process: com.example.okhttpexceptionsample, PID: 13564
E AndroidRuntime: java.lang.NullPointerException: blablabla
E AndroidRuntime:    at com.example.okhttpexceptionsample.MainActivity$createNPEInterceptor$1.intercept(MainActivity.kt:61)
E AndroidRuntime:    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
E AndroidRuntime:    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
E AndroidRuntime:    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
E AndroidRuntime:    at okhttp3.RealCall$AsyncCall.run(RealCall.kt:136)
E AndroidRuntime:    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E AndroidRuntime:    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E AndroidRuntime:    at java.lang.Thread.run(Thread.java:784)

二.為什么會崩潰

從上面的stacktrace,我們可以分析到,發生了NullPointerException。發生了崩潰。

等等,我記得OkHttp有處理異常的情況呢。

嗯,確實,OkHttp有處理異常的情況,比如發生異常會調用onFailure。比如下面的Callback的內容介紹。

interface Callback {
  /**
   * Called when the request could not be executed due to cancellation, a connectivity problem or
   * timeout. Because networks can fail during an exchange, it is possible that the remote server
   * accepted the request before the failure.
   */
  fun onFailure(call: Call, e: IOException)

  /**
   * Called when the HTTP response was successfully returned by the remote server. The callback may
   * proceed to read the response body with [Response.body]. The response is still live until its
   * response body is [closed][ResponseBody]. The recipient of the callback may consume the response
   * body on another thread.
   *
   * Note that transport-layer success (receiving a HTTP response code, headers and body) does not
   * necessarily indicate application-layer success: `response` may still indicate an unhappy HTTP
   * response code like 404 or 500.
   */
  @Throws(IOException::class)
  fun onResponse(call: Call, response: Response)
}

是的.

  • OkHttp只處理了IOException的情況,
  • NullPointerException不是IOException的子類

所以沒有被處理,發生了崩潰。

那么有沒有辦法解決,讓這種崩潰不發生,對用戶不進行干擾呢?其實是可以的。

三.使用Interceptor

package com.example.okhttpexceptionsample

import okhttp3.Interceptor
import okhttp3.Response
import java.io.IOException

/**
 * 對于Interceptor的intercept中可能出現的Throwable包裹成IOExceptionWrapper,轉成網絡請求失敗,而不是應用崩潰
 */
class SafeGuardInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        try {
            return chain.proceed(chain.request())
        } catch (t: Throwable) {
            throw IOExceptionWrapper("SafeGuarded when requesting ${chain.request().url}", t)
        }
    }
}

/**
 * 將chain.proceed處理中發生的Throwable包裝成IOExceptionWrapper
 */
class IOExceptionWrapper(message: String?, cause: Throwable?) : IOException(message, cause)

上面的代碼,我們將任何Throwable的轉成IOExceptionWrapper(偽裝成IOException),然后添加到OkHttpClient中

fun createOKHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .addInterceptor(SafeGuardInterceptor())
            .build()
    }

當我們再次執行有NPE的代碼,日志就發生了改變(不再是崩潰的日志,而是異常的日志)

W System.err: com.example.okhttpexceptionsample.IOExceptionWrapper: SafeGuarded=blablabla
  W System.err:   at com.example.okhttpexceptionsample.SafeGuardInterceptor.intercept(SafeGuardInterceptor.kt:12)
  W System.err:   at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
  W System.err:   at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
  W System.err:   at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
  W System.err:   at okhttp3.RealCall$AsyncCall.run(RealCall.kt:136)
  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:784)
  W System.err: Caused by: java.lang.NullPointerException: blablabla
  W System.err:   at com.example.okhttpexceptionsample.MainActivity$createNPEInterceptor$1.intercept(MainActivity.kt:61)
  W System.err:   at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
  W System.err:   at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
  W System.err:   at com.example.okhttpexceptionsample.SafeGuardInterceptor.intercept(SafeGuardInterceptor.kt:10)
  W System.err:   ... 7 more

上述需要注意兩點

  • 添加的是Interceptor,而不是NetworkInterceptor
  • 順序很重要,一定要放在第一個位置

    四.這么做有什么問題

    這么做,當然可以明顯增強請求的穩定性和應用的崩潰率。但是是不是也有一些問題呢?比如

  • 將問題情況吞掉,不利于發現問題呢
    確實可能存在上述的問題,但是我們可以利用下面的方式減輕或者解決問題
  • 只針對release情況應用SafeGuardInterceptor,這樣便于debug情況下更容易發現
  • 針對不同的build variants進行配置,便于盡可能的小范圍發現問題
  • 實行更加智能的動態開啟策略。

在軟件工程中,很多決定都是trade-off的體現,具體的實施方案大家可以自行平衡選擇。

關于我

更多Android高級面試合集放在github上面了
,需要的小伙伴可以點擊關于我?聯系我獲取
非常希望和大家一起交流 , 共同進步

目前是一名程序員,不僅分享 Android開發相關知識,同時還分享技術人成長歷程,包括個人總結,職場經驗,面試經驗等,希望能讓你少走一點彎路。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

都昌县| 望都县| 武鸣县| 余江县| 池州市| 高要市| 舒城县| 绍兴市| 西盟| 莱阳市| 临漳县| 丰都县| 响水县| 托里县| 泰安市| 扎鲁特旗| 荥阳市| 聂拉木县| 新安县| 汶川县| 清原| 灵璧县| 安福县| 武冈市| 蓬溪县| 陆良县| 麻栗坡县| 白城市| 寻乌县| 诏安县| 磐安县| 呼伦贝尔市| 武邑县| 邯郸县| 隆子县| 北海市| 海林市| 尼木县| 永春县| 宁陕县| 侯马市|