Android加載大圖片不OutOfMemoryError

Android加載圖片時,對于分辨率小,配置低的機子,很容易發生OutOfMemoryError。手機的內存比圖片的大很多,怎么會這樣?

在設置Android虛擬機的內存時:

RAM:模擬器的內存空間

VM Heapdalvik虛擬機最大占用內存,也就是單個進程的最大占用內存。

VM Heap高配的手機,可能有32M,64M,128M,而低配的手機,一般是16M,分辨率越大的手機,一般分配的也比較多。

Android系統對dalvik的vm heapsize作了硬性限制,當java進程申請的java空間超過閾值時,就會拋出OOM異常。也就是說RAM充足也會發生OOM的異常。

--------------------

VM Heap大小16mb,當應用加載一張大圖時,加載圖片所需要的內存空間不是按照圖片大小算的,而是按照圖片的像素點來算的。

圖片像素點計算:

1張叫juhua.jsp的圖片,大小1.27MB,分辨率:3840*2160,24位。

* Android保存圖片像素信息,是用ARGB保存
?* A:0-255,需要一個長度為8的二進制數字,占用1個字節
?* R:0-255,需要一個長度為8的二進制數字,占用1個字節
?* G:0-255,需要一個長度為8的二進制數字,占用1個字節
?* B:0-255,需要一個長度為8的二進制數字,占用1個字節

3840*2160*4=33177600字節/1024/1024=31.640MB
超過了VM Heap的16MB,報內存溢出
10-27 06:16:27.645: I/dalvikvm-heap(1894): Forcing collection of SoftReferences for 33177612-byte allocation
10-27 06:16:27.645: E/dalvikvm-heap(1894): Out of memory on a 33177612-byte allocation.
10-27 06:16:27.655: E/AndroidRuntime(1894): Caused by: java.lang.OutOfMemoryError

************************************
解決方法:
按比例縮小圖片,再加載。
現有手機屏幕分辨率 320*480
寬比:3840/320=12
高比:2160/480=4

選擇比例大的數字12

縮放后再設置,就不會溢出了。
31.640MB/12=2.64mb


代碼例子:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity" ><Buttonandroid:id="@+id/btn1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="點擊加載大圖片(OOO)"android:onClick="loadPic"/><Buttonandroid:id="@+id/btn2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/btn1"android:text="點擊縮放加載大圖片"android:onClick="scaleLoadPic"/><ImageView android:id="@+id/iv_pic"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/btn2"/></RelativeLayout>

package com.example.loadbigpic;import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.widget.ImageView;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void loadPic(View v){/** BitmapFactory.decodeResource(?,?)* 這個帶兩個參數的方法:第一個參數是包含你要加載的位圖資源文件的對象(一般寫成 getResources()就ok了);* 第二個時你需要加載的位圖資源的Id。BitmapFactory.decodeResource(?,?,?)帶三個參數的方法:前兩個和上面的方法一樣。第三個參數應該是對你要加載的位圖是否需要完整顯示,如果你只需要部分,可以在這里定制。*/Bitmap bm=BitmapFactory.decodeResource(getResources(),R.drawable.juhua);ImageView iv_pic=(ImageView) findViewById(R.id.iv_pic);iv_pic.setImageBitmap(bm);}public void scaleLoadPic(View v){Options opts=new Options();//默認為false,設為true,則decoder返回null,//即BitmapFactory.decodeResource(getResources(),R.drawable.juhua,opts);返回null//但會返回圖片的參數的信息到Options對象里//不解析圖片到內存里opts.inJustDecodeBounds=true;BitmapFactory.decodeResource(getResources(),R.drawable.juhua,opts);//獲取圖片的寬,高int imageWidth=opts.outWidth;int imageHeigth=opts.outHeight;//獲取屏幕的高寬Display dp=getWindowManager().getDefaultDisplay();//在高版本里有新的方法獲取,但圖片加載是常用功能,要兼容低版本,所以過時了也用int screenWidth=dp.getWidth();int screenHeight=dp.getHeight();//計算縮放比例int scale=1;int scaleWidth=imageWidth/screenWidth;int scaleHeight=imageHeigth/screenHeight;//取縮放比例,取那個大的值if(scaleWidth>=scaleHeight && scaleWidth>=1){scale=scaleWidth;}else if(scaleWidth<scaleHeight && scaleHeight>=1){scale=scaleHeight;}//設置縮放比例opts.inSampleSize=scale;opts.inJustDecodeBounds=false;Bitmap bm=BitmapFactory.decodeResource(getResources(),R.drawable.juhua,opts);ImageView iv_pic=(ImageView) findViewById(R.id.iv_pic);iv_pic.setImageBitmap(bm);}}







本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/539997.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539997.shtml
英文地址,請注明出處:http://en.pswp.cn/news/539997.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

任務計劃、chkconfig工具、systemd管理服務、unit、target

比如備份數據或者重啟服務。 crontab -u、-e、-l、-r&#xff08;刪除&#xff09; 格式&#xff1a;分 時 日 月 周 user command 文件/var/spool/cron/username 分范圍0-59&#xff0c;時范圍0-23&#xff0c;日范圍1-31&#xff0c;月范圍1-12&#xff0c;周1-7 可用格式1-5…

vue打卡日歷_Vue日歷

new Vue({el: ‘#calendar‘,data: {currentDay: 1,currentMonth: 1,currentYear: 1970,currentWeek: 1,days: [],addDay: [],},created: function() {this.initData(null);var $this this;//請求數據$.ajax({url: "這里填接口名稱",type: "POST",data: {…

android Intent機制詳解

原文出處&#xff1a;http://blog.csdn.net/t12x3456/article/details/7688154 什么是Intent Intent是一種運行時綁定&#xff08;run-time binding&#xff09;機制&#xff0c;它能在程序運行過程中連接兩個不同的組件。通過Intent&#xff0c;你的程序可以向Android表達某種…

python基本數據類型(四)-集合與運算符-python3筆記

1.集合 2.字典 3.運算符優先級 1.集合 創建&#xff1a;() set() 注意&#xff1a;創建空的集合要用set() 特點&#xff1a;元素唯一&#xff0c;無序 運算&#xff1a; &&#xff08;交集&#xff09; |&#xff08;并集&#xff09; -&#xff08;差集&#xff0…

Android的權限

Android有四種權限&#xff1a; 1、Permission 權限 2、Root權限 3、Bootloader的解鎖 4、Radio(基帶)解鎖 ------------------------------------ 1、Permission 我們在開發中經常使用到 Permission 權限&#xff0c;即一系列"Android.Permission.*"對象。…

hive2 java連接_用Java代碼通過JDBC連接Hiveserver2

1.在終端啟動hiveserver2#hiveserver22.使用beeline連接hive另外打開一個終端&#xff0c;輸入如下命令(xavierdb必須是已經存在的數據庫)#beeline -u jdbc:hive2://localhost:10000/xavierdb -n hive -p hive3.添加maven依賴org.apache.hivehive-jdbc1.1.0junitjunit4.9org.ap…

java 向上拋異常_Java 異常的處理方式throws

在昨天的文章《Java 異常的分類與處理》中我們簡單地了解了一下在方法聲明的位置上使用throws關鍵字向上拋出異常&#xff0c;下面深入講解異常的第一種處理方式throws。下面深入講解異常的第一種處理方式throws。看以下例子&#xff1a;import java.io.*;public class Excepti…

Jquery mobile 解決IOS9selectli閃退問題

升級IOS9后&#xff0c;JQuery mobile 出現了個bug問題。<select>&#xff0c;<ul><li></li></ul> 出現閃退。 解決方法&#xff1a; 必須加在 jquery.js 和 jquerymobile.js 中間 <script src"......../...../jquery-2.0.0.min.js&qu…

JAVA通過SSL證書創建MS AD賬戶及設置密碼

近期由于工作需要整理一下自動化的東西&#xff0c;因為公司去年上線了OA&#xff0c;所以公司的入職系統會提交用戶的信息到IT部門&#xff0c;最早的做法是入職到了&#xff0c;IT部門收集用戶信息在AD中創建對應的用戶信息&#xff0c;所以為了提高管理員的工作效率&#xf…

java 實體類規范_實體類的規范

1.Boolean類型1.1.使用Boolean類型,而不是Byte類型1.2.數據庫字段名使用is_開頭1.3.實體類字段名不使用is開頭例子/*** 是否為新消息*/Column(name "is_new_message", nullable false)private Boolean newMessage;2.Enum類型1.使用Convert注解, 并指定coverter類例…

01電話撥號器

實例非常簡單&#xff0c;意在體驗Android的Intent&#xff0c;用戶權限。 Intent 見 http://blog.csdn.net/zengmingen/article/details/49586045 用戶權限 見 http://blog.csdn.net/zengmingen/article/details/49586569 --------------------------------------------------…

微信小程序筆記六模塊化 —— module.exports

微信小程序中所有 js 文件作用域皆為獨立的&#xff0c;每一個 js 文件即為一個模塊。模塊與模塊之間的引用通過 module.exports 或 exports 對外暴露接口。 注意&#xff1a; exports 是 module.exports 的一個引用&#xff0c;因此在模塊里邊隨意更改 exports 的指向會造成未…

java常用的統計_(OJ)Java常用類-統計數字次數

統計數字次數Problem Description命令行輸入一個由數字組成的任意字符串,統計出每個數字出現的次數。Input Description1239586838Output Description0 counts:01 counts:12 counts:13 counts:24 counts:05 counts:16 counts:17 counts:08 counts:39 counts:1解題代碼import ja…

02發送短信

使用SmsManager發送短信java.lang.Object ?android.telephony.SmsManagerManages SMS operations such as sending data, text, and pdu SMS messages. Get this object by calling the static method SmsManager.getDefault().管理短信操作&#xff0c;如發送數據&#xff…

Python運行環境與異常處理

Python的命令格式&#xff1a; python [option] ... [-c cmd | -m mod | file | -] [arg] ... 選項描述-J 啟動將從Python3中刪除或更改某些功能的警告 -B阻止在導入時創建.pyc或.pyo文件-E忽略環境變量-h打印所有可用命令行選項的列表-i在程序執行后進入交互模式-m module以腳…

Java應用一般架構

原文鏈接&#xff1a;http://www.iteye.com/news/31115 當我們架設一個系統的時候通常需要考慮到如何與其他系統交互&#xff0c;所以我們首先需要知道各種系統之間是如何交互的&#xff0c;使用何種技術實現。 1. 不同系統不同語言之間的交互 現在我們常見的不同系統不同語…

Mac MongoDB未正常關閉導致重啟失敗

你可以刪除掉mongod.lock文件&#xff0c;然后重新啟動&#xff0c;如果還是不可以&#xff0c;你可以查看一下進程&#xff0c;然后殺掉&#xff1a; ps -aef | grep mongo sudo kill 1076 再重啟數據庫即可。

微信企業號讓IOS不要識別數字為電話號碼的方法

最近在開發一個聯系人查看功能時&#xff0c;發現IOS端把 8位&#xff0c;11位的數字識別為了 電話號碼。 本來是黑色的樣式&#xff0c;變成了藍色的樣式&#xff0c;還添加了下劃線。點擊一下&#xff0c;還可以撥打電話。 這個問題要改&#xff0c;解決方法很簡單&#xf…

powerdns與nginx結合實現以域名和IP方式訪問web服務器80端口時分別跳轉到不同頁面...

1.powerdns設置 2.內部網站介紹 web服務器采用nginx&#xff0c;內網dns采用powerdns. 想實現的功能如下 通過ip訪問時跳轉到A頁面&#xff0c;通過域名訪問時&#xff0c;讓其跳轉到B頁面。兩種方式的端口均為80. 頁面A對應的nginx配置 server { listen 80; …

Installation error code: -103簽名不一致錯誤

調用Android系統的PackageInstallerActivity進行app安裝時&#xff0c;報Installation error code: -103 錯誤。 原因是&#xff1a;簽名問題。 可能是 1、正安裝的應用沒用簽名 2、正安裝的應用與已安裝的應用包相同&#xff0c;但簽名不同。 解決方法&#xff1a; 1、給…