createBitmap经常抛出outOfMemory异常

时间:2015-09-09 06:06:36

标签: java android bitmap

我的应用程序正在向很多人使用它而抛出了内存异常。我的应用程序创建当前屏幕的位图,然后动画它以在页面之间转换。

    java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View$1.onClick(View.java:4222)
at android.view.View.performClick(View.java:5156)
at android.view.View$PerformClick.run(View.java:20755)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5835)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View$1.onClick(View.java:4217)
... 10 more
Caused by: android.view.InflateException: Binary XML file line #118: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:640)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:689)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:748)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
at com.de_veloper.businessbuilder.MainActivity.premiumMenu(MainActivity.java:558)
... 13 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:614)
... 23 more
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 8683212 byte allocation with 6867876 free bytes and 6MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:726)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:547)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1014)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:3723)
at android.content.res.Resources.loadDrawable(Resources.java:3596)
at android.content.res.TypedArray.getDrawable(TypedArray.java:750)
at android.widget.ImageView.<init>(ImageView.java:151)
at android.widget.ImageView.<init>(ImageView.java:140)
at android.widget.ImageView.<init>(ImageView.java:136)
... 26 more

创建位图的代码

public static Bitmap loadBitmapFromView(View v) {
    Bitmap bitmap;
    v.setDrawingCacheEnabled(true);
    bitmap = Bitmap.createBitmap(v.getDrawingCache());
    bitmap.setHasAlpha(false);
    v.setDrawingCacheEnabled(false);
    return bitmap;
}

动画位图的代码

public void mainMenu(View view) {
    $isonfirstpage = 0;
    $isonmainmenu = 1;
    $isonpremiummenu = 0;
    final RelativeLayout backgroundLayout = (RelativeLayout) findViewById(R.id.activity_background);
    LayoutInflater inflate = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    RelativeLayout newLayout = (RelativeLayout)inflate.inflate(R.layout.main_menu, null);
    Bitmap bitmap = loadBitmapFromView(backgroundLayout);
    Drawable d = new BitmapDrawable(getResources(), bitmap);
    backgroundLayout.removeAllViewsInLayout();
    View mainmenuView = findViewById(R.id.mainmenuView);
    View firstpageView = findViewById(R.id.firstpageView);
    final ImageView screenie = new ImageView(getApplicationContext());
    screenie.setImageDrawable(d);
    backgroundLayout.addView(newLayout);
    backgroundLayout.addView(screenie);
    screenie.animate()
            .translationY(backgroundLayout.getHeight())
            .setDuration(300);


    new Handler().postDelayed(new Runnable() {
        public void run() {
            backgroundLayout.removeView(screenie);

        }
    }, 1500);

}

1 个答案:

答案 0 :(得分:0)

当Bitmap大小为huse时,您将获得OutOfMemory异常,您可以在将位图设置为imageview时解码/缩放位图。

public Bitmap decodeUri(Uri path) throws FileNotFoundException
    {
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(getContentResolver().openInputStream(path),null,o);
        int REQUIRED_SIZE = 100;
        int width_temp = o.outWidth;
        int height_temp = o.outHeight;
        int scale = 1;
        while (true)
        {
            if(width_temp/2 < REQUIRED_SIZE || height_temp/2<REQUIRED_SIZE)
            {
                break;
            }
            width_temp/=2;
            height_temp/=2;
            scale*=2;
        }

        BitmapFactory.Options o1 =new  BitmapFactory.Options();
        o1.inSampleSize = scale;
      return BitmapFactory.decodeStream(getContentResolver().openInputStream(path),null,o1);
    }

您可以将图像路径转换为Uri,如下所示

decodeUri(Uri.fromFile(new File("your file path")))