關(guān)于App調(diào)起第三方支付之后被kill掉的猜想和解決之路

寫(xiě)在前面

今天在開(kāi)發(fā)中,有設(shè)計(jì)新的模塊和功能读跷。

需求是這樣的:在項(xiàng)目產(chǎn)品中會(huì)增加一種新的模塊,叫做精選套餐(項(xiàng)目類(lèi)似于美團(tuán)禾唁,大眾點(diǎn)評(píng)效览,不過(guò)更加專(zhuān)注于精品餐吧和套餐的推送,也專(zhuān)注于夜生活相關(guān)的內(nèi)容荡短,叫做《夜夜》app丐枉,感興趣可以去應(yīng)用市場(chǎng)下載了解下)。這一個(gè)模塊會(huì)涉及到支付掘托, 也就是購(gòu)買(mǎi)瘦锹。在這一個(gè)項(xiàng)目中只是集成支付寶支付和微信支付這兩種比較主流的線(xiàn)上支付方式。

然而我在完成精選套餐模塊的編寫(xiě)之后烫映,模擬了用戶(hù)購(gòu)買(mǎi)套餐沼本,向服務(wù)器發(fā)起了創(chuàng)建訂單的請(qǐng)求,并得到了response锭沟,當(dāng)我把獲得的charge交付給Ping++之后抽兆,我發(fā)現(xiàn)了一個(gè)神奇的想象,就是:

在調(diào)起第三方支付的一瞬間族淮,app被kill掉了辫红!被kill了凭涂!kill了!

what贴妻?what the hell ?what is happening?

這完全是不予許發(fā)生的事情好么切油?而且,更加神奇的是名惩,app被kill之后澎胡,第三方支付竟然還很正常的調(diào)起了,也可以很正常的支付C漯摹9ニ!

這么詭異的現(xiàn)象弯予,生平僅見(jiàn)捌莼隆!不過(guò)稀奇歸稀奇锈嫩,問(wèn)題總是還得解決的受楼。

重啟app之后,去到了訂單中心呼寸,發(fā)現(xiàn)訂單真的是支付成功了艳汽,正安安靜靜的躺在已支付列表里面呢!也就是說(shuō)支付這一個(gè)流程并沒(méi)有錯(cuò)对雪,請(qǐng)求服務(wù)器生成回來(lái)的訂單以及支付的憑證charge也貌似沒(méi)有問(wèn)題骚灸,不然是不會(huì)支付成功的。但是app的確是在調(diào)起支付的一瞬間被kill的慌植,這無(wú)論怎么看都跟支付流程脫不了嫌疑。

竟然在懷疑支付流程义郑,那么就來(lái)試一下:

//startActivityForResult(payIntent);

我把發(fā)起支付的最后一句代碼注釋了一下蝶柿,運(yùn)行之后,發(fā)現(xiàn)app很正常非驮,并沒(méi)有被kill交汤,當(dāng)然同時(shí)并沒(méi)有調(diào)起支付。

好吧劫笙,確實(shí)是跟支付有關(guān)系芙扎。

那么,到底又是有什么關(guān)系呢填大?

回去翻了一下Ping++的文檔戒洼,方向文檔寫(xiě)著服務(wù)端生成的charge是有一定的規(guī)格的,例如title不能超過(guò)30Unicode字符允华,content也有限制圈浇,description也有限制寥掐。那么難道是這一個(gè)套餐的中文名字太長(zhǎng)然后引發(fā)的血案?

但我把支付的憑據(jù)charge log出來(lái)之后發(fā)現(xiàn)磷蜀,其實(shí)都沒(méi)有超過(guò)限制召耘。也就是說(shuō),這個(gè)鍋褐隆,ping++不背污它。

然后仔細(xì)梳理了一下思緒,想起app被kill是在調(diào)起第三方支付的一瞬間發(fā)生庶弃,也就是說(shuō)這一瞬間一定發(fā)生了什么事情衫贬,到時(shí)app掛掉了。但是調(diào)起支付的一瞬間無(wú)非就是app暫時(shí)進(jìn)入后臺(tái)虫埂,然后調(diào)起第三方支付界面祥山,支付完成支付又回到app。那么就是說(shuō)調(diào)起支付一瞬間掉伏,app要暫時(shí)的進(jìn)入后臺(tái)缝呕,之后又要回來(lái),也就是說(shuō)會(huì)調(diào)用onSaveInstanceState()對(duì)app activity當(dāng)前的狀態(tài)進(jìn)行保存斧散,app又在這一瞬間被kill供常,那么問(wèn)題就出現(xiàn)在onSaveInstanceState()的這一個(gè)環(huán)節(jié)上。

真相已經(jīng)很接近了

由于想到是在精選套餐的支付環(huán)節(jié)上才會(huì)出現(xiàn)的問(wèn)題鸡捐,精選套餐又是新增的模塊栈暇,那么問(wèn)題就很可能出現(xiàn)這上面。

由于項(xiàng)目中也有其他的模塊有支付的動(dòng)作箍镜,于是就去測(cè)試了一下源祈。果然,其他所有的支付流程都是正常的色迂。那么罪魁禍?zhǔn)拙褪蔷x套餐模塊了香缺。

通過(guò)對(duì)精選套餐的分析,以及在onSaveInstanceState()進(jìn)行debug歇僧,發(fā)現(xiàn)在保存當(dāng)前activity的時(shí)候图张,保存到變量 mealDetail 終于報(bào)錯(cuò)了同時(shí)app掛掉了。在報(bào)錯(cuò)信息總看到诈悍,原來(lái)是mealDetail 繼承于Serializable祸轮,得以可以序列化。然而mealDetail的一個(gè)內(nèi)部類(lèi)Recommend卻沒(méi)有繼承于Serializable侥钳。因此在app退入后臺(tái)适袜,進(jìn)行事件狀態(tài)保存的一瞬間,對(duì)局部變量進(jìn)行序列化保存時(shí)遇到不能序列化的對(duì)象從而導(dǎo)致的crash慕趴。

所以當(dāng)我把mealDetail的內(nèi)部類(lèi)Recommend繼承于Serializable之后痪蝇,精選套餐的支付流程果然很正常的執(zhí)行了鄙陡。

關(guān)于onSaveInstanceState可以點(diǎn)擊查看說(shuō)明。

基本作用就是

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法躏啰,它們不同于 onCreate()趁矾、onPause()等生命周期方法,它們并不一定會(huì)被觸發(fā)给僵。當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足毫捣、用戶(hù)直接按Home鍵)由系統(tǒng)銷(xiāo)毀一個(gè)Activity時(shí),onSaveInstanceState() 會(huì)被調(diào)用帝际。但是當(dāng)用戶(hù)主動(dòng)去銷(xiāo)毀一個(gè)Activity時(shí)蔓同,例如在應(yīng)用中按返回鍵,onSaveInstanceState()就不會(huì)被調(diào)用蹲诀。因?yàn)樵谶@種情況下斑粱,用戶(hù)的行為決定了不需要保存Activity的狀態(tài)。通常onSaveInstanceState()只適合用于保存一些臨時(shí)性的狀態(tài)脯爪,而onPause()適合用于數(shù)據(jù)的持久化保存则北。

在activity被殺掉之前調(diào)用保存每個(gè)實(shí)例的狀態(tài),以保證該狀態(tài)可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (傳入的Bundle參數(shù)是由onSaveInstanceState封裝好的)中恢復(fù)。這個(gè)方法在一個(gè)activity被殺死前調(diào)用痕慢,當(dāng)該activity在將來(lái)某個(gè)時(shí)刻回來(lái)時(shí)可以恢復(fù)其先前狀態(tài)尚揣。

例如,如果activity B啟用后位于activity A的前端掖举,在某個(gè)時(shí)刻activity A因?yàn)橄到y(tǒng)回收資源的問(wèn)題要被殺掉快骗,A通過(guò)onSaveInstanceState將有機(jī)會(huì)保存其用戶(hù)界面狀態(tài),使得將來(lái)用戶(hù)返回到activity A時(shí)能通過(guò)onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢復(fù)界面的狀態(tài)塔次。

關(guān)于onSaveInstanceState ()方篮,是在函數(shù)里面保存一些View有用的數(shù)據(jù)到一個(gè)Parcelable對(duì)象并返回。在Activity的onSaveInstanceState(Bundle outState)中調(diào)用View的onSaveInstanceState ()励负,返回Parcelable對(duì)象恭取,

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

當(dāng)系統(tǒng)調(diào)用Activity的的onRestoreInstanceState(Bundle savedInstanceState)時(shí)熄守,?同過(guò)Bundle的getParcelable方法得到Parcelable對(duì)象,然后把該P(yáng)arcelable對(duì)象傳給View的onRestoreInstanceState (Parcelable state)耗跛。在的View的onRestoreInstanceState中從Parcelable讀取保存的數(shù)據(jù)以便View使用裕照。

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

總結(jié)

到最后才發(fā)現(xiàn)调塌,原來(lái)所謂的bug還是自己的粗心造成的晋南,只是忽略了onSaveInstanceState()函數(shù)對(duì)于變量的要求從而導(dǎo)致的一系列問(wèn)題的出現(xiàn)。同時(shí)也是自己偷懶羔砾,在創(chuàng)建mealDetail 這一個(gè)數(shù)據(jù)model的時(shí)候用了AndroidStudio的插件GsonFormat直接進(jìn)行生成然后卻沒(méi)有認(rèn)真地檢查负间。(GsonFormat確實(shí)是很吊的一款插件偶妖,很推薦使用,可以省下大量的時(shí)間政溃,當(dāng)然也要細(xì)心的使用趾访,例如我這次的例子)

by the way,擼代碼是一件嚴(yán)肅董虱,細(xì)致扼鞋,一絲不茍的事情,真的馬虎不得愤诱。這次把這么蠢的crash事件碼了出來(lái)云头,就是讓大家嘲笑一下我,這是對(duì)我很好的一個(gè)鞭策淫半。同時(shí)也幫助一下那些可能也遇到這個(gè)問(wèn)題的童鞋們溃槐。

好吧,以后我要認(rèn)真啦科吭,哈哈

如果這篇文章又幫到你的話(huà)昏滴,請(qǐng)點(diǎn)一下‘喜歡’,我會(huì)更努力的創(chuàng)作的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末砌溺,一起剝皮案震驚了整個(gè)濱河市影涉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌规伐,老刑警劉巖蟹倾,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異猖闪,居然都是意外死亡鲜棠,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)培慌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)豁陆,“玉大人,你說(shuō)我怎么就攤上這事吵护『幸簦” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵馅而,是天一觀的道長(zhǎng)祥诽。 經(jīng)常有香客問(wèn)我,道長(zhǎng)瓮恭,這世上最難降的妖魔是什么雄坪? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮屯蹦,結(jié)果婚禮上维哈,老公的妹妹穿的比我還像新娘绳姨。我一直安慰自己,他們只是感情好阔挠,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布飘庄。 她就那樣靜靜地躺著,像睡著了一般谒亦。 火紅的嫁衣襯著肌膚如雪竭宰。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天份招,我揣著相機(jī)與錄音切揭,去河邊找鬼。 笑死锁摔,一個(gè)胖子當(dāng)著我的面吹牛廓旬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谐腰,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼孕豹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了十气?” 一聲冷哼從身側(cè)響起励背,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎砸西,沒(méi)想到半個(gè)月后叶眉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芹枷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年衅疙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸳慈。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饱溢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出走芋,到底是詐尸還是另有隱情绩郎,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布翁逞,位于F島的核電站嗽上,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏熄攘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一彼念、第九天 我趴在偏房一處隱蔽的房頂上張望挪圾。 院中可真熱鬧浅萧,春花似錦、人聲如沸哲思。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)棚赔。三九已至帝簇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間靠益,已是汗流浹背丧肴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胧后,地道東北人芋浮。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像壳快,于是被迫代替她去往敵國(guó)和親纸巷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

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