關于App調起第三方支付之后被kill掉的猜想和解決之路

寫在前面

今天在開發中,有設計新的模塊和功能。

需求是這樣的:在項目產品中會增加一種新的模塊,叫做精選套餐(項目類似于美團,大眾點評,不過更加專注于精品餐吧和套餐的推送,也專注于夜生活相關的內容,叫做《夜夜》app,感興趣可以去應用市場下載了解下)。這一個模塊會涉及到支付, 也就是購買。在這一個項目中只是集成支付寶支付和微信支付這兩種比較主流的線上支付方式。

然而我在完成精選套餐模塊的編寫之后,模擬了用戶購買套餐,向服務器發起了創建訂單的請求,并得到了response,當我把獲得的charge交付給Ping++之后,我發現了一個神奇的想象,就是:

在調起第三方支付的一瞬間,app被kill掉了!被kill了!kill了!

what?what the hell ?what is happening?

這完全是不予許發生的事情好么?而且,更加神奇的是,app被kill之后,第三方支付竟然還很正常的調起了,也可以很正常的支付?。。?/b>

這么詭異的現象,生平僅見?。〔贿^稀奇歸稀奇,問題總是還得解決的。

重啟app之后,去到了訂單中心,發現訂單真的是支付成功了,正安安靜靜的躺在已支付列表里面呢!也就是說支付這一個流程并沒有錯,請求服務器生成回來的訂單以及支付的憑證charge也貌似沒有問題,不然是不會支付成功的。但是app的確是在調起支付的一瞬間被kill的,這無論怎么看都跟支付流程脫不了嫌疑。

竟然在懷疑支付流程,那么就來試一下:

//startActivityForResult(payIntent);

我把發起支付的最后一句代碼注釋了一下,運行之后,發現app很正常,并沒有被kill,當然同時并沒有調起支付。

好吧,確實是跟支付有關系。

那么,到底又是有什么關系呢?

回去翻了一下Ping++的文檔,方向文檔寫著服務端生成的charge是有一定的規格的,例如title不能超過30Unicode字符,content也有限制,description也有限制。那么難道是這一個套餐的中文名字太長然后引發的血案?

但我把支付的憑據charge log出來之后發現,其實都沒有超過限制。也就是說,這個鍋,ping++不背。

然后仔細梳理了一下思緒,想起app被kill是在調起第三方支付的一瞬間發生,也就是說這一瞬間一定發生了什么事情,到時app掛掉了。但是調起支付的一瞬間無非就是app暫時進入后臺,然后調起第三方支付界面,支付完成支付又回到app。那么就是說調起支付一瞬間,app要暫時的進入后臺,之后又要回來,也就是說會調用onSaveInstanceState()對app activity當前的狀態進行保存,app又在這一瞬間被kill,那么問題就出現在onSaveInstanceState()的這一個環節上。

真相已經很接近了

由于想到是在精選套餐的支付環節上才會出現的問題,精選套餐又是新增的模塊,那么問題就很可能出現這上面。

由于項目中也有其他的模塊有支付的動作,于是就去測試了一下。果然,其他所有的支付流程都是正常的。那么罪魁禍首就是精選套餐模塊了。

通過對精選套餐的分析,以及在onSaveInstanceState()進行debug,發現在保存當前activity的時候,保存到變量 mealDetail 終于報錯了同時app掛掉了。在報錯信息總看到,原來是mealDetail 繼承于Serializable,得以可以序列化。然而mealDetail的一個內部類Recommend卻沒有繼承于Serializable。因此在app退入后臺,進行事件狀態保存的一瞬間,對局部變量進行序列化保存時遇到不能序列化的對象從而導致的crash。

所以當我把mealDetail的內部類Recommend繼承于Serializable之后,精選套餐的支付流程果然很正常的執行了。

關于onSaveInstanceState可以點擊查看說明。

基本作用就是

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它們不同于 onCreate()、onPause()等生命周期方法,它們并不一定會被觸發。當應用遇到意外情況(如:內存不足、用戶直接按Home鍵)由系統銷毀一個Activity時,onSaveInstanceState() 會被調用。但是當用戶主動去銷毀一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被調用。因為在這種情況下,用戶的行為決定了不需要保存Activity的狀態。通常onSaveInstanceState()只適合用于保存一些臨時性的狀態,而onPause()適合用于數據的持久化保存。

在activity被殺掉之前調用保存每個實例的狀態,以保證該狀態可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (傳入的Bundle參數是由onSaveInstanceState封裝好的)中恢復。這個方法在一個activity被殺死前調用,當該activity在將來某個時刻回來時可以恢復其先前狀態。

例如,如果activity B啟用后位于activity A的前端,在某個時刻activity A因為系統回收資源的問題要被殺掉,A通過onSaveInstanceState將有機會保存其用戶界面狀態,使得將來用戶返回到activity A時能通過onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢復界面的狀態。

關于onSaveInstanceState (),是在函數里面保存一些View有用的數據到一個Parcelable對象并返回。在Activity的onSaveInstanceState(Bundle outState)中調用View的onSaveInstanceState (),返回Parcelable對象,

接著用Bundle的putParcelable方法保存在Bundle ?savedInstanceState中。

當系統調用Activity的的onRestoreInstanceState(Bundle savedInstanceState)時,?同過Bundle的getParcelable方法得到Parcelable對象,然后把該Parcelable對象傳給View的onRestoreInstanceState (Parcelable state)。在的View的onRestoreInstanceState中從Parcelable讀取保存的數據以便View使用。

這就是onSaveInstanceState() 和?onRestoreInstanceState() 兩個函數的基本作用和用法。

總結

到最后才發現,原來所謂的bug還是自己的粗心造成的,只是忽略了onSaveInstanceState()函數對于變量的要求從而導致的一系列問題的出現。同時也是自己偷懶,在創建mealDetail 這一個數據model的時候用了AndroidStudio的插件GsonFormat直接進行生成然后卻沒有認真地檢查。(GsonFormat確實是很吊的一款插件,很推薦使用,可以省下大量的時間,當然也要細心的使用,例如我這次的例子)

by the way,擼代碼是一件嚴肅,細致,一絲不茍的事情,真的馬虎不得。這次把這么蠢的crash事件碼了出來,就是讓大家嘲笑一下我,這是對我很好的一個鞭策。同時也幫助一下那些可能也遇到這個問題的童鞋們。

好吧,以后我要認真啦,哈哈

如果這篇文章又幫到你的話,請點一下‘喜歡’,我會更努力的創作的

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容