在Android中处理图像的正确方法是什么

时间:2013-07-01 10:38:07

标签: android android-image

public class MainActivity extends Activity implements OnClickListener {

    ImageView imageView1;
    Bitmap s;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // logHeap("ECAonCreate");

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView1 = (ImageView) findViewById(R.id.imageView1);
        imageView1.setBackgroundResource(R.drawable.launchimage20481496);
        // s = decodeFil3e(R.drawable.launchimage20481496);
        ImageButton btn = (ImageButton) findViewById(R.id.btnEnter);
        btn.setOnClickListener(this);
    }

    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) {

            // Calculate ratios of height and width to requested height and
            // width
            final int heightRatio = Math.round((float) height
                    / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }

        return inSampleSize;
    }

    private Bitmap decodeFil3e(int f) {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        o.inTempStorage = new byte[16 * 1024];

        BitmapFactory.decodeResource(getResources(), f, o);

        Display display = getWindowManager().getDefaultDisplay();
        int width = display.getWidth();
        int height = display.getHeight();
        int[] resized = ImageSize(new int[] { o.outWidth, o.outHeight }, width,
                height);

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = calculateInSampleSize(o2, resized[0], resized[1]);
        o2.inTempStorage = new byte[16 * 1024];
        o = null;
        o2 = null;

        return BitmapFactory.decodeResource(getResources(), f, o2);
    }

    @Override
    protected void onDestroy() {

        super.onDestroy();
        imageView1.setBackgroundResource(0);
        imageView1 = null;
        System.gc();
        System.gc();
        logHeap("ECAonDestroyonClick");
    };

    public static int[] ImageSize(int[] imgSize, int maxWidth, int maxHeight) {
        int[] size = new int[2];
        try {
            for (double i = 1; i <= 20; i += 0.1) {
                double height = imgSize[1] / i;
                double width = imgSize[0] / i;
                if (height < maxHeight && width < maxWidth) {
                    size[0] = (int) width;
                    size[1] = (int) height;
                    return size;
                }
            }
            return imgSize;
        } catch (Exception ex) {
            return size;

        }
    }

    public static void logHeap(String functionname) {
        Double allocated = new Double(Debug.getNativeHeapAllocatedSize())
                / new Double((1048576));
        Double available = new Double(Debug.getNativeHeapSize()) / 1048576.0;
        Double free = new Double(Debug.getNativeHeapFreeSize()) / 1048576.0;
        DecimalFormat df = new DecimalFormat();
        df.setMaximumFractionDigits(2);
        df.setMinimumFractionDigits(2);

        Log.d("tag", "debug. =================================");
        Log.d("tag", "debug.heap native: allocated " + df.format(allocated)
                + "MB of " + df.format(available) + "MB (" + df.format(free)
                + "MB free)");
        Log.d("tag",
                "functionname:"
                        + functionname
                        + ":debug.memory: allocated: "
                        + df.format(new Double(Runtime.getRuntime()
                                .totalMemory() / 1048576))
                        + "MB of "
                        + df.format(new Double(
                                Runtime.getRuntime().maxMemory() / 1048576))
                        + "MB ("
                        + df.format(new Double(Runtime.getRuntime()
                                .freeMemory() / 1048576)) + "MB free)");
    }

    @Override
    protected void onResume() {
        super.onResume();
        logHeap("ECAonResume");
    };

    public void onClick(View v) {

        Intent a = new Intent(this, Activity2.class);
        startActivity(a);
        finish();
        //imageView1.setBackgroundResource(0);
        //imageView1 = null;
        //System.gc();
        //System.gc();
        //logHeap("ECAonDestroyonClick");
    }

}

在图1中,堆大小没有减少: enter image description here

您可以看到堆大小减少: enter image description here

我面临一个奇怪的问题 如果我从onClick事件中取消注释以下代码

,我的堆内存将被释放
//      imageView1.setBackgroundResource(0);
//      imageView1 = null;
//      System.gc();
//      System.gc();
//      logHeap("ECAonDestroyonClick");

但是如果我在onDestory事件中放置相同的代码,那么什么都不起作用。 我哪里弄错了? 处理图像的正确方法是什么?

java.lang.OutOfMemoryError: bitmap size exceeds VM budget.

当您尝试在程序中加载几个大位图时,这是您在android中经常遇到的一个短语。为什么?因为应用程序可用的堆大小是有限的,并且大位图是最简单的耗尽方式。 那么你如何解决它?

1 个答案:

答案 0 :(得分:0)

package com.example.mathjax_issues;

import java.text.DecimalFormat;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Debug;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.ImageView;

public class MainActivity extends Activity implements OnClickListener {

    ImageView imageView1;
    Bitmap s;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // logHeap("ECAonCreate");

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView1 = (ImageView) findViewById(R.id.imageView1);
        imageView1.setBackgroundResource(R.drawable.ic_launcher);
        // s = decodeFil3e(R.drawable.launchimage20481496);
        ImageButton btn = (ImageButton) findViewById(R.id.button1);
        btn.setOnClickListener(this);
    }

    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) {

            // Calculate ratios of height and width to requested height and
            // width
            final int heightRatio = Math.round((float) height
                    / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }

        return inSampleSize;
    }

    private Bitmap decodeFil3e(int f) {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        o.inTempStorage = new byte[16 * 1024];

        BitmapFactory.decodeResource(getResources(), f, o);

        Display display = getWindowManager().getDefaultDisplay();
        int width = display.getWidth();
        int height = display.getHeight();
        int[] resized = ImageSize(new int[] { o.outWidth, o.outHeight }, width,
                height);

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = calculateInSampleSize(o2, resized[0], resized[1]);
        o2.inTempStorage = new byte[16 * 1024];
        o = null;
        o2 = null;

        return BitmapFactory.decodeResource(getResources(), f, o2);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("jarvis", "on desttroy executed");
        imageView1.setBackgroundResource(0);
        imageView1 = null;
        logHeap("ECAonDestroyonClick");
        System.gc();
        logHeap("ECAonDestroyonClick");

    };

    public static int[] ImageSize(int[] imgSize, int maxWidth, int maxHeight) {
        int[] size = new int[2];
        try {
            for (double i = 1; i <= 20; i += 0.1) {
                double height = imgSize[1] / i;
                double width = imgSize[0] / i;
                if (height < maxHeight && width < maxWidth) {
                    size[0] = (int) width;
                    size[1] = (int) height;
                    return size;
                }
            }
            return imgSize;
        } catch (Exception ex) {
            return size;

        }
    }

    public static void logHeap(String functionname) {
        Double allocated = new Double(Debug.getNativeHeapAllocatedSize())
                / new Double((1048576));
        Double available = new Double(Debug.getNativeHeapSize()) / 1048576.0;
        Double free = new Double(Debug.getNativeHeapFreeSize()) / 1048576.0;
        DecimalFormat df = new DecimalFormat();
        df.setMaximumFractionDigits(2);
        df.setMinimumFractionDigits(2);

        Log.e("tag", "debug. =================================");
        Log.e("tag", "debug.heap native: allocated " + df.format(allocated)
                + "MB of " + df.format(available) + "MB (" + df.format(free)
                + "MB free)");
        Log.e("tag",
                "functionname:"
                        + functionname
                        + ":debug.memory: allocated: "
                        + df.format(new Double(Runtime.getRuntime()
                                .totalMemory() / 1048576))
                        + "MB of "
                        + df.format(new Double(
                                Runtime.getRuntime().maxMemory() / 1048576))
                        + "MB ("
                        + df.format(new Double(Runtime.getRuntime()
                                .freeMemory() / 1048576)) + "MB free)");
    }

    @Override
    protected void onResume() {
        super.onResume();
        logHeap("ECAonResume");
    };

    public void onClick(View v) {

       /* Intent a = new Intent(this, Activity2.class);
        startActivity(a);
        finish();*/
        //imageView1.setBackgroundResource(0);
        //imageView1 = null;
        //System.gc();
        //System.gc();
        //logHeap("ECAonDestroyonClick");

    }

}

enter image description here