當前位置:首頁 » 安卓系統 » android圖片載入oom

android圖片載入oom

發布時間: 2022-05-13 05:26:45

Ⅰ android bitmap內存溢出的完美解決方案,Gallery載入大量圖片的時候,總是會oom,大俠們幫忙啊,謝謝啦

用弱引用,目前是解決此問題最好方式 WeakReference, 然後用完及時的賦成null

Ⅱ android 為什麼容易出現oom

頭些年的設備內存容量小,dalvik虛擬機被設置為16M內存運行,為了保留足夠的內存,對於bitmap限制為一半,即8M,8M是個什麼概念呢,如果RAGB8888格式的圖片,8M就是800萬像素的圖片,一般的手機都可以達到甚至超過這個標准。所以通常出現OOM都是在以前的設備上運行解碼圖片的時候產生的。
比較新的版本SDK支持配置largeheap選項,會得到一個較大的運行內存,再加上這兩年設備的內存容量大大增加,幾乎可以與PC相當,這個問題就沒那麼容易出現了。

Ⅲ android編程讀取文件有oom錯誤

Out Of Memory 就是內存爆了,你載入的文件太大了 ,所以導致溢出了。如果你載入圖片,你可以搜一下解決圖片OOM的方法,網路上有很多,還有demo。

Ⅳ android 非同步下載圖片到listview中,報oom異常

對啊,listview需要重繪的,
你就把圖片保存起來就好了啊
然後用callback載入
先判斷是否下載了,下載過了就直接設置,沒下載過再去載入

Ⅳ Android 圖片OOM

你從sd 卡中讀取圖片,要將原圖進行縮放顯示,手機內內存有限,有的圖片資源較大,正如你說的,還是反復讀取,一張圖片就能把它搞死

Ⅵ 如何解決上傳多張圖片時遇到的oom問題

一、OOM問題出現的場景和原因
一個好的app總少不了精美的圖片,所以Android開發中圖片的載入總是避免不了的,而在載入圖片過程中,如果處理不當則會出現OOM的問題。那麼如何徹底解決這個問題呢?本文將具體介紹這方面的知識。
首先我們來總結一下,在載入圖片過程中出現的OOM的場景無非就這么幾種:
1、 載入的圖片過大
2、 一次載入的圖片過多
3、 以上兩種情況兼有
那麼為什麼在以上場景下會出現OOM問題呢?實際上在API文檔中有著明確的說明,出現OMM的主要原因有兩點:
1、移動設備會限制每個app所能夠使用的內存,最小為16M,有的設備分配的會更多,如24、32M、64M等等不一,總之會有限制,不會讓你無限制的使用。
2、在andorid中圖片載入到內存中是以點陣圖的方式存儲的,在android2.3之後默認情況下使用ARGB_8888,這種方式下每個像素要使用4各位元組來存儲。所以載入圖片是會佔用大量的內存。
場景和原因我們都分析完了,下面我們來看看如何解決這些問題。
二、解決大圖載入問題
首先先來解決大圖載入的問題,一般在實際應用中展示圖片時,因屏幕尺寸及布局顯示的原因,我們沒有必要載入原始大圖,只需要按照比例采樣縮放即可。這樣即節省內存又能保證圖片不失真,具體實施步驟如下:
1、在不載入圖片內容的基礎上,去解碼圖片得到圖片的尺寸信息
這里需要用的BitmapFactory的decode系列方法和BitmapFactory.Options。當使用decode系列方法載入圖片時,一定要將Options的inJustDecodeBounds屬性設置為true。
BitmapFactory.Options ptions = new BitmapFactory.Options(); options.inJustDecodeBounds=true; BitmapFactory.decodeFile(path, options);2、根據獲取的圖片的尺寸和要展示在界面的尺寸計算縮放比例。public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height reqHeight || width reqWidth) { if (width height) { inSampleSize = Math.round((float) height / (float) reqHeight); } else { inSampleSize = Math.round((float) width / (float) reqWidth); } } return inSampleSize; }3、根據計算的比例縮放圖片。//計算圖片的縮放比例 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds = false; Bitmap bitmap= BitmapFactory.decodeFile(path, options);
根據縮放比例,會比原始大圖節省很多內存,效果圖如下:

三、批量載入大圖
下面我們看看如何批量載入大圖,首先第一步還是我們上面所講到的,要根據界面展示圖片控制項的大小來確定圖片的縮放比例。在此我們使用gridview載入本地圖片為例,具體步驟如下:
1、通過系統提供的contentprovider載入外部存儲器中的所有圖片地址private void loadPhotoPaths(){ Cursor cursor= getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null); while(cursor.moveToNext()){ String path = cursor.getString(cursor.getColumnIndex(MediaColumns.DATA)); paths.add(path); } cursor.close(); }2、自定義adapter,在adapter的getview方法中載入圖片@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder=null; if(convertView==null){ convertView = LayoutInflater.from(this.mContext).inflate(R.layout.grid_item_layout, null); holder = new ViewHolder(); holder.photo=(ImageView)convertView.findViewById(R.id.photo); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } final String path = this.paths.get(position); holder.photo.setImageBitmap(imageLoader.getBitmapFromCache(path)); return convertView; }
通過以上關鍵兩個步驟後,我們發現程序運行後,用戶體驗特別差,半天沒有反應,很明顯這是因為我們在主線程中載入大量的圖片,這是不合適的。在這里我們要將圖片的載入工作放到子線程中進行,改造自定義的ImageLoader工具類,為其添加一個線程池對象,用來管理用於下載圖片的子線程。
private ExecutorService executor; private ImageLoader(Context mContxt) { super(); executor = Executors.newFixedThreadPool(3); } //載入圖片的非同步方法,含有回調監聽 public void loadImage(final ImageView view, final String path, final int reqWidth, final int reqHeight, final onBitmapLoadedListener callback){ final Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: Bitmap bitmap = (Bitmap)msg.obj; callback.displayImage(view, bitmap); break; default: break; } } }; executor.execute(new Runnable() { @Override public void run() { Bitmap bitmap = loadBitmapInBackground(path, reqWidth, reqHeight); putBitmapInMemey(path, bitmap); Message msg = mHandler.obtainMessage(1); msg.obj = bitmap; mHandler.sendMessage(msg); } }); }
通過改造後用戶體驗明顯好多了,效果圖如下:

雖然效果有所提升,但是在載入過程中還存在兩個比較嚴重的問題:
1、 圖片錯位顯示
2、 當我們滑動速度過快的時候,圖片載入速度過慢
經過分析原因不難找出,主要是因為我們時候holder緩存了grid的item進行重用和線程池中的載入任務過多所造成的,只需要對程序稍作修改,具體如下:
Adapter中:
holder.photo.setImageResource(R.drawable.ic_launcher); holder.photo.setTag(path); imageLoader.loadImage(holder.photo, path, DensityUtil.dip2px(80), DensityUtil.dip2px(80), new onBitmapLoadedListener() { @Override public void displayImage(ImageView view, Bitmap bitmap) { String imagePath= view.getTag().toString(); if(imagePath.equals(path)){ view.setImageBitmap(bitmap); } } });
ImageLoader中:
executor.execute(new Runnable() { @Override public void run() { String key = view.getTag().toString(); if (key.equals(path)) { Bitmap bitmap = loadBitmapInBackground(path, reqWidth, reqHeight); putBitmapInMemey(path, bitmap); Message msg = mHandler.obtainMessage(1); msg.obj = bitmap; mHandler.sendMessage(msg); } } });
為了獲得更好的用戶體驗,我們還可以繼續優化,即對圖片進行緩存,緩存我們可以分為兩個部分內存緩存磁碟緩存,本文例子載入的是本地圖片所有隻進行了內存緩存。對ImageLoader對象繼續修改,添加LruCache對象用於緩存圖片。
private ImageLoader(Context mContxt) { super(); executor = Executors.newFixedThreadPool(3); //將應用的八分之一作為圖片緩存 ActivityManager am=(ActivityManager)mContxt.getSystemService(Context.ACTIVITY_SERVICE); int maxSize = am.getMemoryClass()*1024*1024/8; mCache = new LruCachestring, bitmap=""(maxSize){ @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes()*value.getHeight(); } }; } //存圖片到緩存 public void putBitmapInMemey(String path,Bitmap bitmap){ if(path==null) return; if(bitmap==null) return; if(getBitmapFromCache(path)==null){ this.mCache.put(path, bitmap); } } public Bitmap getBitmapFromCache(String path){ return mCache.get(path); }/string,
在loadImage方法中非同步載入圖片前先從內存中取,具體代碼請下載案例。
四、總結
總結一下解決載入圖片出現OOM的問題主要有以下方法:
1、 不要載入原始大圖,根據顯示控制項進行比例縮放後載入其縮略圖。
2、 不要在主線程中載入圖片,主要在listview和gridview中使用非同步載入圖片是要注意處理圖片錯位和無用線程的問題。
3、 使用緩存,根據實際情況確定是否使用雙緩存和緩存大小。
小夥伴們看懂了嘛?想要自己測試的,可以點擊下載工程運行測試哦!

Ⅶ android oom是怎麼引起的

OOM產生可能的原因是因為 1、載入大圖片導致內存溢出 2、大量內存泄露

Ⅷ Android 開發中怎樣載入圖像才能避免OOM

進行緩存,好多第三方封裝好的載入圖片的框架,UniversalImageLoader、Picasso、Fresco、Glide等等都是github上面開源的。
貼出鏈接自己去下載:https://github.com/nostra13/Android-Universal-Image-Loader
https://github.com/square/picasso
https://github.com/bumptech/glide

Ⅸ android如何載入超大解析度圖片

因為你要求圖片不能縮放,不能降低質量,而且有7M,oom是必須的,所以你能做的只能是載入你看得見的地方,意思就是說剪裁著看,先不載入,按屏幕的解析度的1.5倍或多一些進行剪裁(這個度自己控制項),當向某一個方向滑時,檢測坐標如果快超出時,載入右邊的下一幅。
這個有點類似於游戲中的地圖貼圖,也是分塊的。

Ⅹ oom 是什麼意思

OOM Killer(Out of Memory Killer) 是當系統內存嚴重不足時 linux 內核採用的殺掉進程,釋放內存的機制。

OOM Killer 通過檢查所有正在運行的進程,然後根據自己的演算法給每個進程一個 badness 分數,擁有最高 badness 分數的進程將會在內存不足時被殺掉。

它打分的演算法如下:

  • 某一個進程和它所有的子進程都佔用了很多內存的將會打一個高分。

  • 為了釋放足夠的內存來解決這種情況,將殺死最少數量的進程(最好是一個進程)。

  • 內核進程和其他較重要的進程會被打成相對較低的分。

  • 上面打分的標准意味著,當 OOM killer 選擇殺死的進程時,將選擇一個使用大量內存,有很多子進程且不是系統進程的進程。

    簡單來講,oom-killer 的原則就是損失最小、收益最大,因此它會讓殺死的進程數盡可能小、釋放的內存盡可能大。在資料庫伺服器上,Mysql 被分配的內存一般不會小,因此容易成為 oom-killer 選擇的對象。

    「既然發生了 OOM,那必然是內存不足,內存不足這個問題產生原因很多。

    首先第一個就是 MySQL 自身內存的規劃有問題,這就涉及到 mysql 相應的配置參數。

    另一個可以想到的原因就是一般部署 MySQL 的伺服器,都會部署很多的監控和定時任務腳本,而這些腳本往往缺少必要的內存限制,導致在高峰期的時候佔用大量的內存,導致觸發 Linux 的 oom-killer 機制,最終 MySQL 無辜躺槍犧牲。」

熱點內容
怎麼電腦密碼 發布:2025-08-10 23:03:53 瀏覽:738
虛擬機下安裝linux 發布:2025-08-10 23:02:21 瀏覽:761
有哪些配置好車 發布:2025-08-10 22:57:19 瀏覽:905
我的世界冷小壞伺服器 發布:2025-08-10 22:51:59 瀏覽:956
windows下編譯php擴展 發布:2025-08-10 22:43:53 瀏覽:726
鏈表反轉c語言 發布:2025-08-10 22:43:40 瀏覽:285
c語言求兩數之和 發布:2025-08-10 22:37:08 瀏覽:774
phptype 發布:2025-08-10 22:29:23 瀏覽:902
ios和android區別 發布:2025-08-10 22:24:00 瀏覽:832
安卓host是什麼意思 發布:2025-08-10 22:23:09 瀏覽:457