天天看點

Android 異步網絡請求導緻的程式崩潰

大家都有這樣的經曆,在app測試階段,在網絡不佳的時候,我們等不及資料加載完畢來回切換頁面的時候往往會導緻程式崩潰,而且非常常見,一般都是跑出NullPointException 空指針異常,罪魁禍首其實就是 context。

這些錯誤全部出現在網絡請求的回調當中,onSuccess, onFailure, onError等等。在這些方法裡面我們一般會用Toast 或者 Dialog來向使用者展示 例如:資料加載錯誤 這樣的提示資訊,當網速比較快的時候确實可以顯示給使用者,但是若網絡不佳,使用者沒等結果傳回就到了其他頁面,那麼此頁面的Activity context就會為 null,調show 的時候就會報 空指針異常。解決這種問題的方法有很多,

  1. 網絡回調肯定有一個父類,在父類的回調中判斷context是否為空,若為空直接ruturn,這樣就不會調用自己的實作了。
  2. 自己重寫Dialog,在show中統一處理,或者是提供給外部一個靜态方法來初始化和顯示dialog,在此靜态方法中做處理
  3. 關于Toast,有的同學可能會說context 可以使用 getApplicationContext(),這樣的話一般是不會出現crash的,但是 我都到另外一個頁面了你還顯示上一個頁面的加載結果,對使用者來說這就是一種累贅,再者說了,若你的Toast很多的話,Toast會不停的顯示,使用者體驗很差。若确實Toast很多,那麼我們可繼承Toast,寫一個自己的Toast,提供一個靜态方法去顯示Toast,在裡面加上隊列和isRunning 等狀态,這樣可以優化使用者的體驗。

另外一種異常是 Fragment detach Activity,雖然報的異常不一樣,但根本原因還是異步傳回結果後,目前的Activity已經被銷毀,這時context就為空,進行getView、getResource等操作時就會傳回null。解決方案如下(以異步任務為例):

@Override
protected void onPostExecuted(void result){
        if(this.getView() != null){
                //update view
        }
}           
@Override
protected void onStop(){
        if(mTast != null && mTask.getStatus() == Status.RUNNING){
                mTast.stop();
        }
        super.onStop();
}           

通過 isDetach判斷有點不靠譜,可以通過 getView == null 或者是 fragment.isAdded 來判斷