Android?webView加載數(shù)據(jù)時(shí)內(nèi)存溢出問題及解決
Android webView加載數(shù)據(jù)時(shí)內(nèi)存溢出
今天使用webView加載數(shù)據(jù)時(shí) 如果數(shù)據(jù)太長就會(huì)崩潰,造成內(nèi)存溢出,在網(wǎng)上查找了一下資料之后 終于把它解決了,謹(jǐn)在此記錄
1.不要在XML里面寫webView 可以使用一個(gè)占位布局
<FrameLayout ? ? android:id="@+id/layoutWebView" ? ? android:layout_width="match_parent" ? ? android:layout_height="wrap_content" ? ? android:visibility="gone"/>
2.在代碼中動(dòng)態(tài)創(chuàng)建一個(gè)webView 把這個(gè)webView放到FrageLayout這個(gè)布局中
webView = new WebViewMod(getApplicationContext()); WebSettings settings = webView.getSettings(); settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); layoutWebView.addView(webView);
3.到這里基本就OK了,你可以直接在這個(gè)WebView里面加載數(shù)據(jù)了
WebViewMod 這個(gè)是我自定義的一個(gè)webView 用系統(tǒng)的WebView效果是一樣的
4.在當(dāng)前Activity銷毀的時(shí)候 記得在onDestroy方法中銷毀這個(gè)WebView
@Override protected void onDestroy() { ? ? webView.removeAllViews(); ? ? webView.destroy(); ? ? super.onDestroy(); }
大功告成!
Android內(nèi)存問題 (內(nèi)存溢出 內(nèi)存泄漏 內(nèi)存抖動(dòng))
內(nèi)存溢出:指程序在申請(qǐng)內(nèi)存時(shí),沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory
Android系統(tǒng)為每個(gè)應(yīng)用程序申請(qǐng)到的內(nèi)存有限,一般為64M或者128M等,我們可以在清單文件中進(jìn)行配置,android:largeheap = "true" 從而給APP申請(qǐng)更大的內(nèi)存空間;
內(nèi)存泄漏: 指程序在申請(qǐng)內(nèi)存后,被某個(gè)對(duì)象一直持有,無法釋放已申請(qǐng)的內(nèi)存空間
一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很嚴(yán)重,無論多少內(nèi)存,遲早會(huì)被占光。
區(qū)別:單例模式在Android開發(fā)中會(huì)經(jīng)常用到,但是如果使用不當(dāng)就會(huì)導(dǎo)致內(nèi)存泄露。因?yàn)閱卫撵o態(tài)特性使得它的生命周期同應(yīng)用的生命周期一樣長,如果一個(gè)對(duì)象已經(jīng)沒有用處了,但是單例還持有它的引用,那么在整個(gè)應(yīng)用程序的生命周期它都不能正常被回收,從而導(dǎo)致內(nèi)存泄露
如何避免呢?全局的上下文Application Context就是應(yīng)用程序的上下文,和單例的生命周期一樣長,這樣就避免了內(nèi)存泄漏。單例模式對(duì)應(yīng)應(yīng)用程序的生命周期,所以我們?cè)跇?gòu)造單例的時(shí)候盡量避免使用Activity的上下文,而是使用Application的上下文
靜態(tài)變量導(dǎo)致內(nèi)存泄露?靜態(tài)變量存儲(chǔ)在方法區(qū),它的生命周期從類加載開始,到整個(gè)進(jìn)程結(jié)束。
一旦靜態(tài)變量初始化后,它所持有的引用只有等到進(jìn)程結(jié)束才會(huì)釋放。
如何解決呢?Info作為Activity的靜態(tài)成員,并且持有Activity的引用,但是sInfo作為靜態(tài)變量,生命周期肯定比Activity長。
所以當(dāng)Activity退出后,sInfo仍然引用了Activity,Activity不能被回收,這就導(dǎo)致了內(nèi)存泄露。
非靜態(tài)內(nèi)部類導(dǎo)致內(nèi)存泄露?非靜態(tài)內(nèi)部類(包括匿名內(nèi)部類)默認(rèn)就會(huì)持有外部類的引用,當(dāng)非靜態(tài)內(nèi)部類對(duì)象的生命周期比外部類對(duì)象的生命周期長時(shí),就會(huì)導(dǎo)致內(nèi)存泄露。
常見 (Handler,Thread,AsyncTask)
未取消注冊(cè)或回調(diào)導(dǎo)致內(nèi)存泄露?比如我們?cè)贏ctivity中注冊(cè)廣播,如果在Activity銷毀后不取消注冊(cè),那么這個(gè)剛播會(huì)一直存在系統(tǒng)中,同上面所說的非靜態(tài)內(nèi)部類一樣持有Activity引用,導(dǎo)致內(nèi)存泄露。因此注冊(cè)廣播后在Activity銷毀后一定要取消注冊(cè)
集合中的對(duì)象未清理造成內(nèi)存泄露?在循環(huán)中把引用o釋放了,但是它被添加到了objectList中,所以objectList也持有對(duì)象的引用,此時(shí)該對(duì)象是無法被GC的。因此對(duì)象如果添加到集合中,還必須從中刪除,最簡單的方法防止集合類泄漏內(nèi)存的方法
解決辦法:置空集合對(duì)象即可
資源未關(guān)閉或釋放導(dǎo)致內(nèi)存泄露?在使用流或者等資源時(shí)要及時(shí)關(guān)閉。這些資源在進(jìn)行讀寫操作時(shí)通常都使用了緩沖,如果及時(shí)不關(guān)閉,這些緩沖對(duì)象就會(huì)一直被占用而得不到釋放,以致發(fā)生內(nèi)存泄露。因此我們?cè)诓恍枰褂盟鼈兊臅r(shí)候就及時(shí)關(guān)閉,以便緩沖能及時(shí)得到釋放,從而避免內(nèi)存泄露
解決辦法Webview下面的持有Activity引用,造成Webview內(nèi)存無法釋放,即使是調(diào)用了Webview.destory()}等方法都無法解決問題(Android5.1之后)。
最終的解決方案是:在銷毀WebView之前需要先將WebView從父容器中移除,然后在銷毀WebView。
內(nèi)存抖動(dòng):是指在短時(shí)間內(nèi)有大量的對(duì)象被創(chuàng)建或者被回收的現(xiàn)象,內(nèi)存抖動(dòng)出現(xiàn)原因主要是頻繁(很重要)在循環(huán)里創(chuàng)建對(duì)象(導(dǎo)致大量對(duì)象在短時(shí)間內(nèi)被創(chuàng)建,由于新對(duì)象是要占用內(nèi)存空間的而且是很頻繁
內(nèi)存抖動(dòng)結(jié)果:如果抖動(dòng)很頻繁,會(huì)導(dǎo)致垃圾回收機(jī)制頻繁運(yùn)行(短時(shí)間內(nèi)產(chǎn)生大量對(duì)象,需要大量內(nèi)存,而且還是頻繁抖動(dòng),就可能會(huì)需要回收內(nèi)存以用于產(chǎn)生對(duì)象,垃圾回收機(jī)制就自然會(huì)頻繁運(yùn)行了)。綜上就是頻繁內(nèi)存抖動(dòng)會(huì)導(dǎo)致垃圾回收頻繁運(yùn)行。
盡量避免在循環(huán)體內(nèi)創(chuàng)建對(duì)象,應(yīng)該把對(duì)象創(chuàng)建移到循環(huán)體外。
注意自定義View的onDraw()方法會(huì)被頻繁調(diào)用,所以在這里面不應(yīng)該頻繁的創(chuàng)建對(duì)象。
當(dāng)需要大量使用Bitmap的時(shí)候,試著把它們緩存在數(shù)組中實(shí)現(xiàn)復(fù)用。
對(duì)于能夠復(fù)用的對(duì)象,同理可以使用對(duì)象池將它們緩存起來。
小結(jié):JVM以Class為執(zhí)行單元,Android虛擬機(jī)以Dex執(zhí)行單元,編譯流程JVM直接通過Javac即可加載。
Android 虛擬機(jī)需要先編譯成dex,然后編譯成apk。最后執(zhí)行
Android Art虛擬機(jī)在安裝的時(shí)候講dex緩存本地機(jī)器碼,安裝比較慢,耗存儲(chǔ)空間
Android Dalvik虛擬機(jī)在程序運(yùn)行過程中進(jìn)行翻譯。節(jié)省空間,耗cpu時(shí)間。以空間換時(shí)間的典型
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Android跨應(yīng)用啟動(dòng)實(shí)例詳解
這篇文章主要介紹了 Android跨應(yīng)用啟動(dòng)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04Android 如何保證service在后臺(tái)不被kill
本文主要介紹了Android 如何保證service在后臺(tái)不被kill的方法。具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-02-02給Android初學(xué)者的Gradle知識(shí)普及
剛學(xué) Android 不久,對(duì) Gradle 不懂,看了很多資料依然一知半解,很多人都這樣覺得,表示同感,下面小編來給大家講講 Gradle相關(guān)知識(shí),需要的朋友跟隨小編一起來學(xué)習(xí)一下2018-09-09Android仿新浪微博oauth2.0授權(quán)界面實(shí)現(xiàn)代碼(2)
這篇文章主要為大家詳細(xì)介紹了Android仿新浪微博oauth2.0授權(quán)界面實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11Android實(shí)現(xiàn)WebView點(diǎn)擊攔截跳轉(zhuǎn)原生
這篇文章主要介紹了Android實(shí)現(xiàn)WebView點(diǎn)擊攔截跳轉(zhuǎn)原生,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03Android自定義控件實(shí)現(xiàn)帶數(shù)值和動(dòng)畫的圓形進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)帶數(shù)值和動(dòng)畫的圓形進(jìn)度條,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12Android RecyclerView網(wǎng)格布局示例解析
這篇文章主要介紹了Android RecyclerView網(wǎng)格布局示例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12Android幀式布局實(shí)現(xiàn)自動(dòng)切換顏色
這篇文章主要為大家詳細(xì)介紹了Android幀式布局實(shí)現(xiàn)自動(dòng)切換顏色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04Android Jetpack組件DataBinding詳解
這篇文章主要介紹了Android Jetpack組件DataBinding,DataBinding有很多優(yōu)勢(shì),其中最明顯是代碼更加簡潔,可讀性會(huì)更高。部分和UI控件有關(guān)的代碼可以在布局文件當(dāng)中完成,本文給大家詳細(xì)講解,需要的朋友可以參考下2022-10-10