Service的onStartCommand方法報NullPointerException

引言

最近發(fā)現(xiàn)一個偶發(fā)性bug,根據(jù)崩潰堆棧顯示,在Service的onStartCommand方法中獲取的intent對象為空。

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.getBooleanExtra(java.lang.String, boolean)' on a null object reference  

首先需要明確兩點:1、在Service啟動的時候,的確傳了Intent對象;2、這是一個偶發(fā)性的bug

代碼分析

在Service的onStartCommand方法中有一個flag標(biāo)志位,有如下取值:
START_STICKY:如果service進(jìn)程被kill掉,保留service的狀態(tài)為開始狀態(tài),但不保留遞送的intent對象。隨后系統(tǒng)會嘗試重新創(chuàng)建service,由于服務(wù)狀態(tài)為開始狀態(tài),所以創(chuàng)建服務(wù)后一定會調(diào)用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到service,那么參數(shù)Intent將為null。
START_NOT_STICKY:“非粘性的”。使用這個返回值時,如果在執(zhí)行完onStartCommand后,服務(wù)被異常kill掉,系統(tǒng)將會把它置為started狀態(tài),系統(tǒng)不會自動重啟該服務(wù),直到startService(Intent intent)方法再次被調(diào)用;
START_REDELIVER_INTENT:重傳Intent。使用這個返回值時,如果在執(zhí)行完onStartCommand后,服務(wù)被異常kill掉,系統(tǒng)會自動重啟該服務(wù),并將Intent的值傳入;
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保證服務(wù)被kill后一定能重啟。

因為我所用的Service是需要利用Intent傳遞參數(shù)的,所有在Service被異常kill的時候,希望系統(tǒng)重啟Service能把Intent的值頁傳進(jìn)來。按常理來說,將標(biāo)志位設(shè)置成START_REDELIVER_INTENT應(yīng)該就OK了。然而我貌似就是這樣設(shè)置的,但是還是出現(xiàn)空指針異常。

在Stack Overflow上看到這樣一段話:
Are you possibly confusing [START_FLAG_REDELIVERY](http://developer.android.com/reference/android/app/Service.html#START_FLAG_REDELIVERY) with [START_REDELIVER_INTENT](http://developer.android.com/reference/android/app/Service.html#START_REDELIVER_INTENT)? Your post says, "the return value START_FLAG_REDELIVERY ". That constant is not one of the values returned from [onStartCommand](http://developer.android.com/reference/android/app/Service.html#onStartCommand(android.content.Intent,%20int,%20int)), it is one of the bit values passed into onStartCommand as the flags parameter. START_FLAG_REDELIVERY and START_STICKY both have value of 1. If you mistakenly have return START_FLAG_REDELIVERY at the end of onStartCommand() , the service will restart in sticky mode with a null intent if there are no start commends pending.

有START_FLAG_REDELIVERY和START_REDELIVER_INTENT兩個標(biāo)志位,而且兩個標(biāo)志位代表的意思還不一樣。這里粘貼一下Document里面的原文:

Android Develop截圖

結(jié)論

保險起見,還是在傳進(jìn)來的Intent做一次判空

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容