Android使用Intent傳大數(shù)據(jù)簡單實(shí)現(xiàn)詳解
前言
最近想不出什么比較好的內(nèi)容,但是碰到一個(gè)沒畢業(yè)的小老弟問的問題,那就借機(jī)說說這個(gè)事。Intent如何傳大數(shù)據(jù)?為什么是簡單的說,因?yàn)檫@背后深入的話,有很多底層的細(xì)節(jié)包括設(shè)計(jì)思想,我也不敢說完全懂,但我知道當(dāng)你用Intent傳大數(shù)據(jù)報(bào)錯(cuò)的時(shí)候應(yīng)該怎么解決,并且簡單聊聊這背后所涉及到的東西。
Intent傳大數(shù)據(jù)
平時(shí)可能不會(huì)發(fā)生這種問題,但比如我之前是做終端設(shè)備的,我的設(shè)備每秒都會(huì)生成一些數(shù)據(jù),而長時(shí)間的話數(shù)據(jù)量自然大,這時(shí)當(dāng)我跳到另外一個(gè)頁面使用intent把數(shù)據(jù)傳過去的時(shí)候,就會(huì)報(bào)錯(cuò)
我們調(diào)用
intent.putExtra("key", value) // value超過1M
會(huì)報(bào)錯(cuò)
android.os.TransactionTooLargeException: data parcel size xxx bytes
這里的xxx就是1M左右,告訴你傳輸?shù)臄?shù)據(jù)大小不能超過1M,有些話咱也不敢亂說,有點(diǎn)怕誤人子弟。我這里是憑印象說的,如果有大佬看到我說錯(cuò),請(qǐng)狠狠的糾正我。
這個(gè)錯(cuò)誤描述是這么描述,但真的是限死1M嗎,說到這個(gè),就不得不提一樣?xùn)|西,Binder機(jī)制,先不要跑,這里不會(huì)詳細(xì)講Binder,只是提一嘴。
說到Binder那就會(huì)聯(lián)系到mmap內(nèi)存映射,你可以先簡單理解成內(nèi)存映射是分配一塊空間給內(nèi)核空間和用戶空間共用,如果還是不好理解,就簡單想成分配一塊空間通信用,那在android中mmap分配的空間是多少呢?1M-4K。
那是不是說Intent傳輸?shù)臄?shù)據(jù)超過1M-4K就會(huì)報(bào)錯(cuò),理論上是這樣,但實(shí)際沒到這個(gè)值,比如0.8M也可能會(huì)報(bào)錯(cuò)。所以你不能去走極限操作,比如你的數(shù)據(jù)到了1M,你覺得只要減少點(diǎn)數(shù)據(jù),減到8K,應(yīng)該就能過了,也許你自己測試是正常的,但是這很危險(xiǎn)。
所以能不傳大數(shù)據(jù)就不要傳大數(shù)據(jù),它的設(shè)計(jì)初衷也不是為了傳大數(shù)據(jù)用的。如果真要傳大數(shù)據(jù),也不要走極限操作。
那怎么辦,切莫著急,請(qǐng)聽我慢慢講。就這個(gè)Binder它是什么玩意,它是Android中獨(dú)特的進(jìn)程通信的方式,而Linux中進(jìn)程通信的方式,在Android中同樣也適用。進(jìn)程間通信有很多方式,Binder、管道、共享內(nèi)存等。為什么會(huì)有這么多種通信方式,因?yàn)槊糠N通信方式都有自己的特點(diǎn),要在不同的場合使用不同的通信方式。
為什么要提這個(gè)?因?yàn)橐炊@個(gè)問題,你需要知道Binder這種通信方式它有什么特點(diǎn),它適合大量的數(shù)據(jù)傳輸嗎?那你Binder又與我Intent何干,你抓周樹人找我魯迅干嘛~~所以這時(shí)候你就要知道Android四大組件之間是用什么方式通信的。
有點(diǎn)扯遠(yuǎn)了,現(xiàn)在可以來說說結(jié)論了,Binder沒辦法傳大數(shù)據(jù),我就1M不到你想怎樣?當(dāng)然它不止1M,只是Android在使用時(shí)限制了它只能最多用1M,內(nèi)核的最大限制是4M。又有點(diǎn)扯遠(yuǎn)了,你不要想著怎么把限制擴(kuò)大到4M,不要往這方面想。前面說了,不同的進(jìn)程通信方式,有自己的特點(diǎn),適用于某些特定的場景。那Binder不適用于傳輸大數(shù)據(jù),我共享內(nèi)存行不行?
所以就有了解決辦法
bundle.putBinder()
有人可能一看覺得,這有什么不同,這在表面上看差別不大,實(shí)則內(nèi)部大大的不同,bundle.putBinder()用了共享內(nèi)存,所以能傳大數(shù)據(jù),那為什么這里會(huì)用共享內(nèi)存,而putExtra不是呢?想搞清楚這個(gè)問題,就要看源碼了。 這里就不深入去分析了,我怕勸退,不是勸退你們,是勸退我自己。有些東西是這樣的,你要自己去看懂,看個(gè)大概就差不多,但是你要講出來,那就要看得細(xì)致,而有些細(xì)節(jié)確實(shí)會(huì)勸退人。所以想了解為什么的,可以自己去看源碼,不想看的,就知道這是怎么一回事就行。
那還有沒有其它方式呢?當(dāng)然有,你不懂共享內(nèi)存,你寫到本地緩存中,再從本地緩存中讀取行不行?
辦法有很多,如果你不知道這個(gè)問題怎么解決,你找不到你覺得可行的解決方案,甚至可以通過邏輯通過流程的方式去繞開這個(gè)問題。但是你要知道為什么會(huì)出現(xiàn)這樣的問題,如果你沒接觸過進(jìn)程通信,沒接觸過Binder,讓你看一篇文章就能看懂我覺得不切實(shí)際,但是至少得知道是怎么一回事。
比如我只說bundle.putBinder()能解決這個(gè)問題,你一試,確實(shí)能解決,但是不知道為什么,你又怕會(huì)不會(huì)有其它問題。雖然這篇文章我一直在打擦邊球,沒有提任何的原理,但我覺得還是能大概讓人知道為什么bundle.putBinder()能解決Intent傳大數(shù)據(jù),你也就能放心去用了。
以上就是Android使用Intent傳大數(shù)據(jù)簡單實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于Android Intent傳大數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android TreeView實(shí)現(xiàn)帶復(fù)選框樹形組織結(jié)構(gòu)
這篇文章主要為大家詳細(xì)介紹了Android TreeView實(shí)現(xiàn)帶復(fù)選框樹形組織結(jié)構(gòu),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07解決android studio引用遠(yuǎn)程倉庫下載慢(JCenter下載慢)
這篇文章主要介紹了解決android studio引用遠(yuǎn)程倉庫下載慢(JCenter下載慢),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Android Flutter實(shí)現(xiàn)淘寶App的搜索推薦
這篇文章主要為大家詳細(xì)介紹了Android?Flutter如何模擬實(shí)現(xiàn)淘寶App的搜索推薦,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的可以了解一下2023-07-07AndroidStuio插件開發(fā)適用于jetbrains全家桶
這篇文章主要介紹了AndroidStuio插件開發(fā)適用于jetbrains全家桶,本文通過實(shí)例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12Android應(yīng)用中使用ViewPager和ViewPager指示器來制作Tab標(biāo)簽
這篇文章主要介紹了Android中使用ViewPager和ViewPager指示器來制作Tab標(biāo)簽的方法,ViewPager指示器ViewPageIndicator是一個(gè)開源庫,文中舉了一個(gè)仿網(wǎng)易新聞客戶端Tab標(biāo)簽的例子,需要的朋友可以參考下2016-03-03