[android] 03_加载大图片到内存

Android 4.0

加载大图片到内存
加载大图片,加载一张大图片
加载大图片到内存
android为每一个应用程序都分配了一个dalvik虚拟机,每一个dalvik虚拟机有最大内存限制,
目前一般都是16M,高端的32M,有的平板64M
核心代码:
package cn.zengfansheng.loadpic;
 
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
 
public class MainActivity extends Activity {
 
    private ImageView iv;
    private WindowManager wm;
    private int windowHeight;
    private int windowWidth;
 
    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        iv = (ImageView) this.findViewById(R.id.iv);
 
        // TODO 1、获取手机屏幕大小
        wm = (WindowManager) this.getSystemService(WINDOW_SERVICE);
        // 1-1 高版本获取屏幕大小
        // Point outSize = new Point();
        // wm.getDefaultDisplay().getSize(outSize);// Call requires API level 13 (current min is 8):android.view.Display#getSize
 
        // 1-2低版本获取屏幕大小
        windowWidth = wm.getDefaultDisplay().getWidth();
        windowHeight = wm.getDefaultDisplay().getHeight();
    }
 
    /**
     * 加载一张图片
     * @param view
     */

    public void loadPic(View view) {
 
        /*
        这是不行的,当图片大小超过dalvik虚拟机内存带下,会出现OOM异常
        String file = Environment.getExternalStorageDirectory()+"/fireworks.jpg";
        System.out.println("file:"+file);
        Bitmap bitmap = BitmapFactory.decodeFile(file);
        iv.setImageBitmap(bitmap);*/

 
        // 解决方案:
        // 1.获取图片的宽高
        // 2.获取手机屏幕的宽高
        // 3.分别计算水平和竖直方向的缩放比例.
        // 4.重新设置真正的解析Bitmap
 
        // TODO 2、获取图片大小
        String file = Environment.getExternalStorageDirectory()+"/fireworks.jpg";
        Options opts = new Options();
        opts.inJustDecodeBounds = true;// 如果为true,不去真正的解析bitmap 只是解析bitmap的头信息.
        BitmapFactory.decodeFile(file, opts);//whether the image should be completely decoded, or just is size returned.
        // 参数2:null,完全加载图片到内存,否则按比例缩放加载
        int outWidth = opts.outWidth;
        int outHeight = opts.outHeight;
        System.out.println("图片宽:" + outWidth);
        System.out.println("图片高:" + outHeight);
        System.out.println("屏幕宽:" + windowWidth);
        System.out.println("屏幕高" + windowHeight);
 
        // TODO 3、缩放比例
        int scale = 1;
        int scaleX = outWidth / windowWidth;
        int scaleY = outHeight / windowHeight;
        if (scaleX > scaleY) {
            scale = scaleX;
        } else {
            scale = scaleY;
        }
        opts.inSampleSize = scale;// 如果大于1,比如4,那么尺寸为原来的1/4 * 1/4 = 1/16的大小;如果<=1,和原来大小一致。
        System.out.println("缩放比例:" + scale);
 
        // TODO 4、重新设置真正的解析Bitmap
        opts.inJustDecodeBounds = false;
 
        Bitmap bitmap = BitmapFactory.decodeFile(file, opts);
        iv.setImageBitmap(bitmap);
    }
}
结果:


问题:如果图片过大,会报下面的异常
10-19 02:19:41.794: W/dalvikvm(1698): 31961104 byte allocation exceeds the 16777216 byte maximum heap size
10-19 02:19:41.954: E/AndroidRuntime(1698): java.lang.IllegalStateException: Could not execute method of the activity
10-19 02:19:41.954: E/AndroidRuntime(1698): Caused by: java.lang.reflect.InvocationTargetException