setImageBitmap错误,ImageView调用OutOfMemory

时间:2016-04-11 14:01:57

标签: java android out-of-memory android-bitmap

GitHub错误的项目:https://github.com/MediaPortal1/HowToDraw/blob/master/app/src/main/java/com/poltavets/app/

我的项目中有方法img.setImageResources(R.id.image),但是当我经常使用这种方法或更改屏幕方向时,它会调用OutOfmemory。 我发现这篇关于加载位图图像的文章“正确”:https://developer.android.com/training/displaying-bitmaps/load-bitmap.html 复制粘贴2本文的最后一个方法,并从以下位置更改我的代码:

       imageView.setImageResource(image);

TO:

 Handler handler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                if(getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
                    imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,100,100));
                else imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,400,400));
            }
        };
        handler.sendEmptyMessage(image);

我把这些方法放到Handler上,它的工作速度更快。并且我添加了方向条件,因为在陆地中,ImageView较小,而位图必须具有较小的分辨率。它工作正常,everithink还可以。但是我在这个项目中使用了另一个细节(只是将图像添加到我的项目中),并重新构建了这个项目2-3次,当我开始活动时再次出现OutOfMemory错误。在此错误出现之前并不总是如此,但现在它在我启动Activity时始终出现!怎么样?我不讨论这项活动的代码?我的图像真的很低。最大图像尺寸200kb。大小为100kb的图像如何调用OutOfMemory?

错误:

Process: com.poltavets.app.howtodraw, PID: 28720    java.lang.OutOfMemoryError: Failed to allocate a 35389452 byte allocation with 5482128 free bytes and 5MB until OOM
    at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
    at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:655)
    at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:488)
    at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:511)
    at com.poltavets.app.howtodraw.view.HowTo.decodeSampledBitmapFromResource(HowTo.java:224)
    at com.poltavets.app.howtodraw.view.HowTo$3.handleMessage(HowTo.java:185)
    at android.os.Handler.dispatchMessage(Handler.java:111)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5546)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)

ChangeImage代码(错误在这里):

    public void changeImageSrc(int image,int count,int position,String name) {
            filename=name+"_"+image+"_"+position;
            imagenumber=position;
            if(move!=null || back!=null) {
                move.setEnabled(false);
                back.setEnabled(false);
            }
            Handler handler=new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    if(getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
                        imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,100,100));

 else imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,400,400)); // OUT OF MEMORY ERROR
                }
            };
            handler.sendEmptyMessage(image);

            getSupportActionBar().setTitle(getResources().getString(R.string.title_how_to) + " " + name + ": " + (position+1)+"/"+(count));
                if(position==0 || position+1==count){
                    if(position==0){
                        findViewById(R.id.backBtn).setEnabled(false);
                        findViewById(R.id.backBtn).setVisibility(View.INVISIBLE);
                    }
                    else {
                        findViewById(R.id.moveBtn).setEnabled(false);
                        findViewById(R.id.moveBtn).setVisibility(View.INVISIBLE);
                        Toast.makeText(getApplicationContext(),getString(R.string.finish),Toast.LENGTH_SHORT).show();
                    }
                }
                else {
                    showNavButtons();
                }
            if(move!=null || back!=null) {
                move.setEnabled(true);
                back.setEnabled(true);
            }

谷歌文章的两种方法:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                         int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }

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

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

1 个答案:

答案 0 :(得分:0)

我什么也没做。我重新建造了这个项目3-4次,但没有帮助。但我现在只是重新构建它而没有任何变化,而且它有效。