首先,我们试着往sdcard里放一张400k的图片,但是分辨率是2560*1600

  布局简单

<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.dell.myapplication.MainActivity"> <Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="loading ima"
android:id="@+id/button" android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:layout_below="@+id/button"
android:layout_centerHorizontal="true"
android:layout_marginTop="213dp"/>
</RelativeLayout>

  MainActivity

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView; public class MainActivity extends AppCompatActivity {
Button mbutton;
ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mbutton= (Button) findViewById(R.id.button);
mImageView= (ImageView) findViewById(R.id.imageView);
mbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Bitmap bitmap= BitmapFactory.decodeFile("/storage/sdcard/test.JPG");//将图片转换为bitmap
mImageView.setImageBitmap(bitmap);
}
});
}
}

  很简单,设置点击按钮开始加载图片

  结果:

  报的错误:

    08-16 21:17:08.410 2947-2947/com.example.dell.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
                java.lang.OutOfMemoryError
                at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
              at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:530)
                at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:303)
                at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:329)
                at com.example.dell.myapplication.MainActivity$1.onClick(MainActivity.java:23)
                at android.view.View.performClick(View.java:4240)
                at android.view.View$PerformClick.run(View.java:17721)
                at android.os.Handler.handleCallback(Handler.java:730)
                at android.os.Handler.dispatchMessage(Handler.java:92)
                at android.os.Looper.loop(Looper.java:137)
                at android.app.ActivityThread.main(ActivityThread.java:5103)
                at java.lang.reflect.Method.invokeNative(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:525)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                at dalvik.system.NativeStart.main(Native Method)

  这时候,你可能会想,天呐,我的图片明明只有400Kb啊,怎么可能会OutOfMemoryError!!是我的虚拟机太腊鸡了吗?

  其实不是这样

  在Android下采用ARGB来表示颜色  每个像素占4byte。
 
  那么这张图片在Android虚拟机中实际占用内存:2560*1600*4byte=15.6M而我们的虚拟机创建时,Dalvik默认堆得大小是16M,所以这时基本就OOM了。(因为堆上还  有别的东西)
 
  这时候就要对我们的图片进行缩放
 
  那么,如何缩放?当然是根据分辨率缩放。我们将图片和我们的虚拟机进行对比
 
  图片:2560*1600
  手机:320*480
 
  宽缩放: 8
  高缩放: 3
 
  按照大的比例来缩放,这样缩放后的尺寸肯定宽高都小于等于手机的尺寸。
 
  具体方法:
  1 得到图片的分辨率
  2 得到手机的分辨率
  3缩放
 
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView; public class MainActivity extends AppCompatActivity {
Button mbutton;
ImageView mImageView;
int screenWidth;
int screenHeight; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); WindowManager wm= (WindowManager) getSystemService(WINDOW_SERVICE);
screenWidth= wm.getDefaultDisplay().getWidth();
screenHeight=wm.getDefaultDisplay().getHeight();
System.out.print("手机宽"+screenWidth+"手机高"+screenHeight); mbutton= (Button) findViewById(R.id.button);
mImageView= (ImageView) findViewById(R.id.imageView);
mbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//创建bitmap工厂的配置参数
BitmapFactory.Options options=new BitmapFactory.Options();
//返回null,不去真正解析位图,只是得到宽高等信息
options.inJustDecodeBounds=true;
BitmapFactory.decodeFile("/storage/sdcard/test.JPG",options);
int imgWidth=options.outWidth;
int imgHeight=options.outHeight;
System.out.print("图片宽"+imgWidth+"图片高"+imgHeight); // 计算缩放比
int scale=1;
int scalex=imgWidth/screenWidth;
int scaley=imgHeight/screenHeight;
scale=scalex>scaley?scalex:scaley;
//按照缩放比显示图片
options.inSampleSize=scale;
//开始真正解析位图
options.inJustDecodeBounds=false;
Bitmap bitmap=BitmapFactory.decodeFile("/storage/sdcard/test.JPG",options);
mImageView.setImageBitmap(bitmap);
}
});
}
}
  结果:

  打印结果:

  08-16 22:03:22.542 9790-9790/com.example.dell.myapplication I/System.out: 手机宽320手机高480
  08-16 22:03:38.432 9790-9790/com.example.dell.myapplication I/System.out: 图片宽2560图片高1600

Android加载大图不OOM的更多相关文章

  1. Android 加载大图

    在 Android 开发中, Bitmap 是个吃内存大户,稍微操作不当就会 OOM .虽然现在第三方的图片加载库已经很多,很完善,但是作为一个 Androider 还得知道如何自己进行操作来加载大图 ...

  2. Android加载大图到内存如何避免内存溢出?

    加载大图怎么避免溢出实际做法就是对图像进行压缩,也是比较老的话题了,在最初做android时是经常会遇到的问题,而如今对于图片加载这一块都已经有很成熟稳定的三方库来弄它了,所以图片加载过大内存溢出的比 ...

  3. android加载大图,防止oom

    高效加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状.不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库里展示的图片大都是 ...

  4. Android加载大图片OOM异常解决

      尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过 ...

  5. android -- 加载gif 防止oom

    项目中涉及到gif图片的展示,原来使用的是gifview,但是当频繁的,加载过大图片的时候会出现OOM的问题,后来去github上面找相关的库: https://github.com/koral--/ ...

  6. [android]加载大量图片避免OOM

    原理是事先取得图片的长宽,直接读出缩略图. BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferr ...

  7. Android高效加载大图、多图解决方案,有效避免程序内存溢出现象

    好久没有写博客了,今天就先写一个小的关于在Android中加载大图如何避免内存溢出的问题. 后面会写如何使用缓存技术的核心类,android.support.v4.util.LruCache来加载图片 ...

  8. Android中高效的显示图片之一 ——加载大图

    在网上看了不少文章,发现还是官方文档介绍最详细,把重要的东西简单摘要出来.详细可看官方文档地址 ( http://www.bangchui.org/read.php?tid=9 ) . 在应用中显示图 ...

  9. Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)【系列1】

    Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)[系列1] Android在加载或者处理超大巨型图片 ...

随机推荐

  1. linux中不同颜色的文件代表什么不同的类型

    linux 文件颜色的含义,蓝色代表目录,绿色代表可执行文件,红色表示压缩文件,浅蓝色表示链接文件,灰色表示其他文件,红色闪烁表示链接的文件有问题了,黄色表示设备文件.蓝色文件----------目. ...

  2. C#篇(二)——属性的实质

    属性的内部实现其实就是方法 我们平时写的代码: class Student { private int age; public int Age { get { return age; } set { ...

  3. HDU 4786Fibonacci Tree(最小生成树)

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  4. 【C#Windows 服务】 《三》Timer设置

    一.工具: VS2015+NET Framework4.5. 二.操作: 1.计时器设置: 2.日志代码: 三.代码: 1.日志代码: 1 /// <summary> 2 /// Wind ...

  5. Studio3T 破解,无需命令计划任务

    最近项目中使用到了MongoDB,苦于命令行不好操作,所以就寻觅了一下MongDB的GUI管理工具,最终找到了Studio3T,功能非常强大,但是苦于只有评估版本30天,最可气的是一时手贱,修改了系统 ...

  6. 高并发MYSQL如何优化处理?

    1)代码中sql语句优化 2)数据库字段优化,索引优化 3)加缓存,redis/memcache等 4)主从,读写分离 5)分区表 6)垂直拆分,解耦模块 7)水平切分

  7. Unity Shader (一)ShaderLab 语法

    一.什么是Shader Shader(着色器):是可以在GPU上运行的一段程序,通过Shader可以进行一些渲染相关的设置. 二.什么是ShaderLab 目前面向GPU的编程有三种高级图像语言:HL ...

  8. C语言调试小技巧

    经常看到有人介绍一些IDE或者像gdb这样的调试器的很高级的调试功能,也听人说过有些牛人做工程的时候就用printf来调试,不用特殊的调试器.特别是在代码经过编译器一些比较复杂的优化后,会变得“难以辨 ...

  9. 【Henu ACM Round#16 E】Paths and Trees

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 感觉很像一道最短路. 然后就试了一发. 结果真的是.. 只要用一个优先队列优化的dijkstra算法求出每个点的最短路上的前一个点是 ...

  10. CSU 1249 竞争性酶抑制剂和同工酶

    1249: 竞争性酶抑制剂和同工酶 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 109  Solved: 49 Description 人体内很多化学 ...