欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解決Android平臺(tái)中應(yīng)用程序OOM異常的方法

 更新時(shí)間:2015年12月14日 16:22:45   作者:leehong2005  
這篇文章主要介紹了解決Android平臺(tái)中應(yīng)用程序OOM異常的方法,通常這一塊也是程序中的重點(diǎn)之一,感興趣的小伙伴們可以參考一下

在Android平臺(tái)上面,應(yīng)用程序OOM異常永遠(yuǎn)都是值得關(guān)注的問題。通常這一塊也是程序這中的重點(diǎn)之一。這下我就如何解決OOM作一點(diǎn)簡單的介紹。

首先,OOM就是內(nèi)存溢出,即Out Of Memory。也就是說內(nèi)存占有量超過了VM所分配的最大。

怎么解決OOM,通常OOM都發(fā)生在需要用到大量內(nèi)存的情況下(創(chuàng)建或解析Bitmap,分配特大的數(shù)組等),在這樣的一種情況下,就可能出現(xiàn)OOM,據(jù)我現(xiàn)在了解到,多數(shù)OOM都是因?yàn)锽itmap太大。所以,這里我就專門針對(duì)如何解決Bitmap的OOM。其實(shí)最核發(fā)的就是只加載可見范圍內(nèi)的Bitmap,試想這樣一種情況,在GridView或ListView中,數(shù)據(jù)量有5000,每一屏只顯示20個(gè)元素,那么不可見的,我們是不需要保存Bitmap在內(nèi)在中的。所以我們就是只把那么可見的Bitmap保留在內(nèi)存中,那些不可見的,就釋放掉。當(dāng)元素滑出來時(shí),再去加載Bitmap。

這里我有兩種方式,都可以避免OOM。

一、主動(dòng)釋放Bitmap的內(nèi)存
這種方式我簡單說一下,不太推薦,這也是我最開始使用的一種方法,但最后證明它不是最好的。(不推薦)

它的本質(zhì)思路是:
  1、只加載可見區(qū)域的Bitmap

  2、滑動(dòng)時(shí)不加載

  3、停止滑動(dòng)(Idle)后,開始重新加載可見區(qū)域的圖片

  4、釋放滑出可見區(qū)域的Bitmap的內(nèi)在。

它比較復(fù)雜:
    1、我們需要監(jiān)聽GridView/ListView的滑動(dòng)事件,這個(gè)很簡單做到,AbsListView#setOnScrollListener(OnScrollListener l)

    2、主動(dòng)調(diào)用Bitmap#recycle()方法,它會(huì)導(dǎo)致一個(gè)問題,必須判斷這個(gè)Bitmap是否被一個(gè)View(ImageView等)所引用,如果被引用,我們不能簡單地調(diào)用recycle()方法,這樣會(huì)導(dǎo)致異常,說是View使用了一個(gè)已經(jīng)被回收的Bitmap。

    3,我們必須設(shè)計(jì)自己的線程來控制開始/暫停等,因?yàn)镚ridView/ListView的滑動(dòng)狀態(tài)可能不斷地變化,也就是說滑動(dòng)->停止->滑動(dòng),這種狀態(tài)可能不斷變化,這樣就會(huì)導(dǎo)致我們的線程中的run()方法里面的邏輯比較復(fù)雜,一旦復(fù)雜,問題就可能就得更多。

基于以上幾點(diǎn),這種方式不是最好的,所以不推薦。

二、設(shè)計(jì)Cache
    這種方式,我覺得是比較好的一種,它首先利用了cache,我認(rèn)為cache是一個(gè)很重要的東西,把Bitmap的內(nèi)存單獨(dú)放在一個(gè)地方來管理,這個(gè)地方就是cache,它的容量是一定的,我們可能會(huì)不斷的向這個(gè)cache中添加元素,也可能不斷的移除元素。

為了更好的說明這種方式,先要介紹一下LruCache。

LruCache
    1、這其實(shí)就是一個(gè)LinkedHashMap,任意時(shí)刻,當(dāng)一個(gè)值被訪問時(shí),它就會(huì)被移動(dòng)到隊(duì)列的開始位置,所以這也是為什么要用LinkedHashMap的原因,因?yàn)橐l繁的做移動(dòng)操作,為了提高性能,所以要用LinkedHashMap。當(dāng)cache滿了時(shí),此時(shí)再向cache里面添加一個(gè)值,那么,在隊(duì)列最后的值就會(huì)從隊(duì)列里面移除,這個(gè)值就有可能被GC回收掉。

    2、如果我們想主動(dòng)釋放內(nèi)存,也是可以的,我們可以重寫entryRemoved(Boolean, K, V, V)方法。

    3、這個(gè)類是線程安全的,在多線程下面使用這個(gè)類,沒不會(huì)存在問題。

synchronized (cache) { 
   if (cache.get(key) == null) { 
     cache.put(key, value); 
  }} 

    4、LruCache的APILevel是12,也就是說,我們?cè)赟DK 2.3.x以下是無法使用的,但是沒關(guān)系,LruCache的源碼不算復(fù)雜,我們可以直接把它拷貝到自己的工程目錄就可以了。
 AsyncTask<>
    這個(gè)類也是一個(gè)很重要也很常用的類。它封裝了Thread和Handler,我們使用就更加方便,不用關(guān)注Handler,我們知道,在后臺(tái)線程中是不能更新UI,而很多情況下,我們?cè)诤笈_(tái)線程做完一件事情后,一般都會(huì)更新UI,一般的做法是向關(guān)聯(lián)到UI線程的Handler發(fā)送一個(gè)message,在Handler里面去處理這個(gè)message,從而更新UI。用了AsyncTask之后,我們就不用關(guān)注Handler了。這個(gè)類有幾個(gè)重要的方法:

    1)、onPreExecute(): 在UI線程里面調(diào)用,它在這個(gè)task執(zhí)行后會(huì)立即調(diào)用。我們?cè)谶@個(gè)方法里面通常是用于建立一個(gè)任務(wù),比如顯示一個(gè)等待對(duì)話框來通知用戶。

    2)、doInBackground(Params...):這個(gè)方法從名字就可以看出,它是運(yùn)行在后臺(tái)線程的,在這個(gè)方法里面,去做耗時(shí)的事情,比如下載訪問網(wǎng)絡(luò),操作文件等。這這個(gè)方法里面,我們可以調(diào)用publishProgress(Progress...)來調(diào)用當(dāng)前任務(wù)的進(jìn)度,調(diào)用了這個(gè)方法后,對(duì)應(yīng)的onProgressUpdate(Progress...)方法會(huì)被調(diào)用,這個(gè)方法是運(yùn)行在UI線程的。

    3)、onProgressUpdate(Progress...):運(yùn)行在UI線程,在調(diào)用publishProgress()方法之后。這個(gè)方法用來在UI上顯示任何形式的進(jìn)度,比如你可以顯示一個(gè)等待對(duì)話框,也可以顯示一個(gè)文本形式的log,還可以顯示toast對(duì)話框。

    4)、onPostExecute(Result):當(dāng)task結(jié)束后調(diào)用,它運(yùn)行在UI線程。

    5)、取消一個(gè)task,我們可以在任何時(shí)候調(diào)用cancel(Boolean)來取消一個(gè)任務(wù),當(dāng)調(diào)用了cancel()方法后,onCancelled(Object)方法就會(huì)被調(diào)用,onPostExecute(Object)方法不會(huì)被調(diào)用,在doInBackground(Object[])方法中,我們可以用isCancelled()方法來檢查任務(wù)是否取消。

    6)、幾點(diǎn)規(guī)則

AsyncTask實(shí)例必須在UI線程中創(chuàng)建  
execute(Params...)方法必須在UI線程中調(diào)用。
不用手動(dòng)調(diào)用onPreExecute(), onPostExecute(), doInBackground(), onProgressUpdate()方法。
一個(gè)任務(wù)只能被執(zhí)行一次。 
總的思路
    1、始終從cache中去取Bitmap,如果取到Bitmap,就直接把這個(gè)Bitmap設(shè)置到ImageView上面。

    2、如果緩存中不存在,那么啟動(dòng)一個(gè)task去加載(可能從文件來,也可能從網(wǎng)絡(luò))。

    3、每一個(gè)ImageView上面都可能綁定一個(gè)task,所以,這個(gè)ImageView必須提供一個(gè)方法能得到與之相關(guān)聯(lián)的task,為什么要這樣做?因?yàn)樵诮o一個(gè)ImageView綁定task之前,必須要把原先的task取消。

以上就是解決應(yīng)用程序OOM異常的方法,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • Android使用Canvas?2D實(shí)現(xiàn)循環(huán)菜單效果

    Android使用Canvas?2D實(shí)現(xiàn)循環(huán)菜單效果

    循環(huán)菜單有很多種自定義方式,我們可以利用ViewPager或者RecyclerView?+?CarouselLayoutManager?或者RecyclerView?+?PageSnapHelper來實(shí)現(xiàn)這種效果,今天我們使用Canvas?2D來實(shí)現(xiàn)這種效果,感興趣的朋友可以參考下
    2024-01-01
  • Android 軟鍵盤彈出時(shí)把原來布局頂上去的解決方法

    Android 軟鍵盤彈出時(shí)把原來布局頂上去的解決方法

    本文主要介紹了Android軟鍵盤彈出時(shí)把原來布局頂上去的解決方法。具有一定的參考作用,下面跟著小編一起來看下吧
    2017-01-01
  • Android?startActivityForResult的調(diào)用與封裝詳解

    Android?startActivityForResult的調(diào)用與封裝詳解

    startActivityForResult?可以說是我們常用的一種操作了,目前有哪些方式實(shí)現(xiàn)?startActivityForResult?的功能呢?本文就來和大家詳細(xì)聊聊
    2023-03-03
  • Flutter 使用cached_image_network優(yōu)化圖片加載體驗(yàn)

    Flutter 使用cached_image_network優(yōu)化圖片加載體驗(yàn)

    在 Flutter 中,cached_image_network 即提供了緩存網(wǎng)絡(luò)圖片功能,同時(shí)還提供了豐富的加載過程指示。本文就來看下cached_image_network的具體使用
    2021-05-05
  • Android使用剪切板傳遞數(shù)據(jù)

    Android使用剪切板傳遞數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了Android使用剪切板傳遞數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • Android ListView實(shí)現(xiàn)無限循環(huán)滾動(dòng)

    Android ListView實(shí)現(xiàn)無限循環(huán)滾動(dòng)

    這篇文章主要為大家詳細(xì)介紹了Android ListView實(shí)現(xiàn)無限循環(huán)滾動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • Android三種方式生成矢量圖之VectorDrawable類使用詳解

    Android三種方式生成矢量圖之VectorDrawable類使用詳解

    這篇文章主要介紹了Android三種方式生成矢量圖的VectorDrawable類,2014年6月26日的I/O?2014開發(fā)者大會(huì)上谷歌正式推出了Android?L,它帶來了全新的設(shè)計(jì)語言Material?Design,新的API也提供了這個(gè)類VectorDrawable
    2023-02-02
  • android2.3.5 CDMA/EVDO撥號(hào)APN解決方案

    android2.3.5 CDMA/EVDO撥號(hào)APN解決方案

    google提供的android2.3里面,只能在GSM/WCDMA情況下才能從“設(shè)置”->“無線和網(wǎng)絡(luò)”->“移動(dòng)網(wǎng)絡(luò)”->“接入點(diǎn)名稱”中選擇不同的apn帳號(hào)進(jìn)行撥號(hào)連接,而CDMA/EVDO則沒有這個(gè)功能,接下來本文介紹一些方法實(shí)現(xiàn)這個(gè)功能,感興趣的朋友可以了解下
    2013-01-01
  • android時(shí)間選擇控件之TimePickerView使用方法詳解

    android時(shí)間選擇控件之TimePickerView使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了android時(shí)間選擇控件之TimePickerView的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Android開發(fā)實(shí)現(xiàn)布局幀布局霓虹燈效果示例

    Android開發(fā)實(shí)現(xiàn)布局幀布局霓虹燈效果示例

    這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)布局幀布局霓虹燈效果,涉及Android界面布局、資源文件操作及屬性設(shè)置等相關(guān)技巧,需要的朋友可以參考下
    2019-04-04

最新評(píng)論