關(guān)于NotSerializableException: com.google.gson.internal.StringMap問題總結(jié)

最近項目進(jìn)行了一次target sdk的升級28版本的改造懂鸵,在處理了一些target 版本的Android9.0的兼容之后骚腥,項目整體運行起來沒有什么問題,但在之后作為SDK給另一個項目使用之后出現(xiàn)了一個比較罕見的問題-NotSerializableException: com.google.gson.internal.StringMap數(shù)據(jù)序列化問題哈恰,看似比較簡單,也是困擾了很久烟馅,下面總結(jié)一下針對這個問題的跟蹤查詢阻肿。


錯誤日志

一傅是、問題描述

? ? 我在進(jìn)行功能驗證的過程中發(fā)現(xiàn)了一個比較奇怪的問題,當(dāng)我在頁面A的時候數(shù)據(jù)沒有任何問題构订,也可以正常顯示侮叮,但是不管我從頁面A(Fragment)跳轉(zhuǎn)到任何頁面B、C悼瘾、D(Activity囊榜,F(xiàn)ragment都行)都會崩潰审胸,控制臺輸出問題截圖上面的的異常信息。然而我從其他頁面E(Fragment)跳轉(zhuǎn)到B卸勺、C砂沛、D的時候都沒有任何問題。

????根據(jù)控制臺的異常日志輸出信息可以看出這就是一個簡單的序列化問題曙求,剛開始我是這么認(rèn)為的碍庵,日志信息明確說明了是PageBean的寫入數(shù)列化問題,那我們就找PageBean然后實現(xiàn)序列化就可以了悟狱。當(dāng)我找到PageBean的時候就懵了?public class PageBeanimplements Serializable {}静浴,明明都已經(jīng)實現(xiàn)了Serializable 接口了,為什么還是報錯了挤渐,是不是子類沒有實現(xiàn)Serializable 接口呢苹享!然后我仔細(xì)檢查了PageBean的每個子類以及子類的子類,全部都實現(xiàn)了Serializable 接口浴麻,問題開始變得復(fù)雜了得问。回頭又看錯誤日志软免,發(fā)現(xiàn)還有一個信息宫纬,就是StringMap這個類,但是我搜索了一個引用的gson庫并沒有找個這個文件或杠。

二哪怔、問題定位?

我把問題同步給了項目leader宣蔚,經(jīng)過leader跟同事的連夜查找向抢,總算是大概定位到了問題所在,而且也找到了StringMap這個類胚委。那天我早早的可恥的溜了挟鸠,事后也是感到非常的慚愧。原來StringMap是在早些的gson庫里所存在幫助json數(shù)據(jù)解析的類亩冬,而我們的項目的gson比較新艘希,所以一直找不到這個類,我們的另一個項目是早些的gson庫硅急,所以打包后到另一個項目才會出現(xiàn)此問題覆享。出問題的地方大概在下面所存在的寫入序列化對象的代碼中

public static TemplateContainerFragment newInstance(ChannelNavBean channelNavBean, PageBean firstPageBean) {

????TemplateContainerFragment vesselFragment = new TemplateContainerFragment();

????Bundle bundle = new Bundle();

????bundle.putSerializable(AppParams.INTENT_PARAM_CHANNEL_NAV_BEAN, channelNavBean);

? ? if (firstPageBean != null) {

? ? ????bundle.putSerializable(AppParams.INTENT_PARAM_CHANNEL_PAGE_BEAN, firstPageBean);

????}

????vesselFragment.setArguments(bundle);

????return vesselFragment;

}

大概定到問題以后,leader為了鍛煉我解決問題的能力营袜,也是拋給我2個問題撒顿,希望我能多提高自己解決問題的能力

????1.序列化是在什么時候出問題的?出問題的序列化對象在什么位置上?SrtingMap對象在當(dāng)中扮演的角色是什么?

????2.為什么頁面初始化的時候沒有問題,反而在進(jìn)入下一級頁面的時候出現(xiàn)崩潰?

三、問題分析

? ? 根據(jù)日志信息和已找到的代碼可以大概確定PageBean是在序列化的時候出現(xiàn)了問題,我找到上面的相關(guān)代碼進(jìn)行debug驗證,尋找PageBean中未實現(xiàn)序列化的StringMap對象,還真的有所發(fā)現(xiàn)

產(chǎn)生StringMap的PageBean

? ? 為什么PageBean里面會有StringMap對象荚板?帶著這個疑問我跟蹤查找了一個StringMap的產(chǎn)生凤壁,終于在gson庫里面的ObjectTypeAdapter對象中找到了StringMap的產(chǎn)生吩屹,原來是在數(shù)據(jù)解析的時候如果有JSONArray有未知的List<Object> list,Object會被轉(zhuǎn)化成為一個StringMap對象存儲拧抖,而StringMap是沒有序列化的對象煤搜,所以在傳遞數(shù)據(jù)的過程中會出現(xiàn)異常。那么第一個問題就找到了答案

public Object read(JsonReader in) throws IOException {

????JsonToken token = in.peek();

????switch(token) {

????????case BEGIN_ARRAY:

????????????????List<Object> list = new ArrayList();

????????????????in.beginArray();

????????while(in.hasNext()) {

????????????list.add(this.read(in));

????????}

????????in.endArray();

????????return list;

????????case BEGIN_OBJECT:

????????????????Map<String, Object> map = new StringMap();

????????????????in.beginObject();

????????while(in.hasNext()) {

????????????map.put(in.nextName(), this.read(in));

????????}

????????in.endObject();

????????return map;

????????case STRING:

????????????????return in.nextString();

????????case NUMBER:

????????????????return in.nextDouble();

????????case BOOLEAN:

????????????????return in.nextBoolean();

????????case NULL:

????????????????in.nextNull();

????????????????return null;

????????default:

????????????????throw new IllegalStateException();

????}

}

? ? 剩下的問題就是這個方法明明是在頁面初始化的時候調(diào)用的唧席,為什么在頁面初始化的時候沒有問題擦盾,返回再頁面進(jìn)入下一級頁面的時候回出現(xiàn)崩潰?其實發(fā)現(xiàn)進(jìn)入下一個頁面的時候出現(xiàn)問題淌哟,也就發(fā)現(xiàn)了思路厌衙,進(jìn)入下一級頁面的時候上一個頁面要保存數(shù)據(jù),對绞绒,就是保存數(shù)據(jù)的時候可能會出現(xiàn)問題婶希,然后我就跟蹤onSaveInstanceState(@NonNull Bundle outState)的方法,頁面離開確實調(diào)用了該方法蓬衡,但是outState參數(shù)是空的喻杈,沒有傳遞任何數(shù)據(jù),為什么會出問題呢狰晚,經(jīng)過一系列的跟蹤筒饰,終于在FragmentState中發(fā)現(xiàn)了問題,原來在fragment頁面

@Override

public void writeToParcel(Parcel dest, int flags) {

????dest.writeString(mClassName);

????dest.writeInt(mIndex);

????dest.writeInt(mFromLayout ? 1 : 0);

????dest.writeInt(mFragmentId);

????dest.writeInt(mContainerId);

????dest.writeString(mTag);

????dest.writeInt(mRetainInstance ? 1 : 0);

????dest.writeInt(mDetached ? 1 : 0);

????dest.writeBundle(mArguments);

????dest.writeInt(mHidden ? 1 : 0);

????dest.writeBundle(mSavedFragmentState);

}

Parcel類的writeBundle
bundle類的writeToParcel
writeToParcelInner
writeArrayMapInternal

? ? ? ? for循環(huán)寫入數(shù)據(jù)

writeValue

? ? 寫入數(shù)據(jù),原來這里要求寫入的數(shù)據(jù)對象以及子對象都必須是序列化的數(shù)據(jù)壁晒,否則就會出現(xiàn)異常瓷们。為什么頁面初始化進(jìn)入寫入的數(shù)據(jù)沒有問題,反而在頁面離開保存數(shù)據(jù)的時候?qū)懭氲臄?shù)據(jù)會出現(xiàn)異常秒咐?帶著這個疑問我又看了一下bundle.putSerializable()這個方法谬晕。

Bundle的putSerializable方法
putSerializable

? ? 看到代碼之后我釋然了,原來putSerializable這個方法值值要求傳入的對象被序列化就可以,并不要求子對象必須都實現(xiàn)數(shù)列化接口携取。所以才導(dǎo)致頁面初始化的時候并沒有問題攒钳,反而在頁面離開保存數(shù)據(jù)的時候?qū)懭霐?shù)據(jù)異常。

四雷滋、問題跟蹤解決

由于我們的數(shù)據(jù)PageBean的解析里面JSONArray出現(xiàn)的問題不撑,所以就嘗試在不改變gson庫版本號的同時解決這個問題,于是根據(jù)返回的數(shù)據(jù)結(jié)構(gòu)嘗試把JSONAarray替換成List<JSONObject>形式,于是又做了一番兼容的嘗試工作晤斩,但是由于我們的數(shù)據(jù)結(jié)構(gòu)問題,并沒有成功焕檬,最后還是報出了相同的錯誤,經(jīng)過查看還JSONObject中還是出現(xiàn)了沒有序列化的StringMap。

仍然有問題的PageBean

最后只能溝通把另一個項目的gson庫進(jìn)行升級解決這個問題澳泵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末实愚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌爆侣,老刑警劉巖萍程,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異兔仰,居然都是意外死亡茫负,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門乎赴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忍法,“玉大人,你說我怎么就攤上這事榕吼《鲂颍” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵羹蚣,是天一觀的道長原探。 經(jīng)常有香客問我,道長顽素,這世上最難降的妖魔是什么咽弦? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮胁出,結(jié)果婚禮上型型,老公的妹妹穿的比我還像新娘。我一直安慰自己全蝶,他們只是感情好闹蒜,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抑淫,像睡著了一般绷落。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丈冬,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天嘱函,我揣著相機與錄音甘畅,去河邊找鬼埂蕊。 笑死,一個胖子當(dāng)著我的面吹牛疏唾,可吹牛的內(nèi)容都是我干的蓄氧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼槐脏,長吁一口氣:“原來是場噩夢啊……” “哼喉童!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起顿天,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤堂氯,失蹤者是張志新(化名)和其女友劉穎蔑担,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咽白,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡啤握,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了晶框。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片排抬。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖授段,靈堂內(nèi)的尸體忽然破棺而出蹲蒲,到底是詐尸還是另有隱情,我是刑警寧澤侵贵,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布届搁,位于F島的核電站,受9級特大地震影響窍育,放射性物質(zhì)發(fā)生泄漏咖祭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一蔫骂、第九天 我趴在偏房一處隱蔽的房頂上張望么翰。 院中可真熱鬧,春花似錦辽旋、人聲如沸浩嫌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽码耐。三九已至,卻和暖如春溶其,著一層夾襖步出監(jiān)牢的瞬間骚腥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工瓶逃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留束铭,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓厢绝,卻偏偏與公主長得像契沫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子昔汉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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

  • 泛型: https://juejin.im/post/5b614848e51d45355d51f792#headi...
    RexHuang閱讀 6,847評論 0 0
  • 概況 Gson是一個Java庫懈万,它可以用來把Java對象轉(zhuǎn)換為JSON表達(dá)式,也可以反過來把JSON字符串轉(zhuǎn)換成與...
    木豚閱讀 6,792評論 0 2
  • 1.概述2.Gson的目標(biāo)3.Gson的性能和擴展性4.Gson的使用者5.如何使用Gson 通過Maven來使用...
    人失格閱讀 14,234評論 2 18
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當(dāng)在唯一索引所對應(yīng)的列上鍵入重復(fù)值時,會觸發(fā)此異常会通。 O...
    我想起個好名字閱讀 5,312評論 0 9
  • 為了更好的學(xué)習(xí)Gson口予,特將Gson User Guide翻譯如下。由于本人英文水平有限涕侈,如有錯誤苹威,還請指正,謝謝...
    WeberLisper閱讀 6,808評論 0 6