位图处理时内存泄漏

时间:2012-05-09 15:10:02

标签: android bitmap out-of-memory

我尝试编写一些相机意图处理程序来拍照和后期处理(如果需要)。如果我在高分辨率上拍摄一些照片我的节目中断了"分配太大"。如果我采取较低分辨率的一些,我可以采取更多,但它也会打破。经过一番搜索,我发现我必须回收位图,我已经手工制作了。但问题并没有消失。我的主要问题是我不知道我的代码中是否存在1.内存泄漏2.我不知道为什么它会尝试分配我没有的内容。在我的程序中显示位图(现在),我只是保存它们以便进一步重用。

public void onClick(View view) {
    Intent i = new Intent("android.media.action.IMAGE_CAPTURE");
    this.mLastPic = new File(this.mFs.getDirPath(), this.mFs.getNextPicName()); //create and save a file for pic
    i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(this.mLastPic));
    this.startActivityForResult(i, 0);
}

on activty result handler

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == Activity.RESULT_OK && requestCode == 0) {

        try {
            if(!this.mController.getSetting(R.string.USE_HEIGH_RESOLUTION)) { //use high res or not
                int quality = this.mFs.getPicQuality(); //get compress quality
                Bitmap pic = BitmapFactory.decodeFile(this.mLastPic.getPath());
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                pic.compress(Bitmap.CompressFormat.JPEG, quality, outStream);
                String path = this.mLastPic.getPath();
                if(this.mLastPic.delete()) { //replace the old file with a now file
                    File newFile = new File(path);
                    newFile.createNewFile();
                    FileOutputStream os = new FileOutputStream(newFile);
                    os.write(outStream.toByteArray());
                    Log.d("newEntryActivity.onActivityResult", "replaced pic ");
                } else {
                    Log.d("newEntryActivity.onActivityResult", "cant delete old pic");
                }
                pic.recycle(); //cleaning up
                outStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

logcat显示

  

05-09 14:35:01.694:E / dalvikvm-heap(845):6380496字节的外部分配对于此过程来说太大了。 05-09 14:35:01.694:E /(845):VM不允许我们分配6380496个字节

     

05-09 14:35:01.694:D / AndroidRuntime(845):关闭虚拟机

     

05-09 14:35:01.694:W / dalvikvm(845):threadid = 3:线程退出时未捕获异常(组= 0x4001b188)

     

05-09 14:35:01.694:E / AndroidRuntime(845):未捕获的处理程序:由于未捕获的异常而导致主线程退出

     

05-09 14:35:01.714:E / AndroidRuntime(845):java.lang.RuntimeException:无法启动活动ComponentInfo {unicorn.Heurazio / unicorn.Heurazio.SettingsActivity}:android.view.InflateException:Binary XML文件行#2:错误导致类...

     

05-09 14:35:01.714:E / AndroidRuntime(845):引起:android.view.InflateException:二进制XML文件行#2:错误导致类

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.view.LayoutInflater.createView(LayoutInflater.java:513)

     

05-09 14:35:01.714:E / AndroidRuntime(845):at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.view.LayoutInflater.inflate(LayoutInflater.java:385)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.view.LayoutInflater.inflate(LayoutInflater.java:320)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.view.LayoutInflater.inflate(LayoutInflater.java:276)

     

05-09 14:35:01.714:E / AndroidRuntime(845):at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.app.Activity.setContentView(Activity.java:1622)

     

05-09 14:35:01.714:E / AndroidRuntime(845):at unicorn.Heurazio.SettingsActivity.onCreate(SettingsActivity.java:38)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)

     

05-09 14:35:01.714:E / AndroidRuntime(845):... 11更多

     

05-09 14:35:01.714:E / AndroidRuntime(845):引起:java.lang.reflect.InvocationTargetException

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.widget.LinearLayout。(LinearLayout.java:92)

     

05-09 14:35:01.714:E / AndroidRuntime(845):at java.lang.reflect.Constructor.constructNative(Native Method)

     

05-09 14:35:01.714:E / AndroidRuntime(845):at java.lang.reflect.Constructor.newInstance(Constructor.java:446)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.view.LayoutInflater.createView(LayoutInflater.java:500)

     

05-09 14:35:01.714:E / AndroidRuntime(845):... 21更多

     

05-09 14:35:01.714:E / AndroidRuntime(845):引起:java.lang.OutOfMemoryError:位图大小超过VM预算

     

05-09 14:35:01.714:E / AndroidRuntime(845):at android.graphics.Bitmap.nativeCreate(Native Method)> 05-09 14:35:01.714:E / AndroidRuntime(845):在android.graphics.Bitmap.createBitmap(Bitmap.java:468)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.graphics.Bitmap.createBitmap(Bitmap.java:435)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:488)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:462)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.content.res.Resources.loadDrawable(Resources.java:1705)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.content.res.TypedArray.getDrawable(TypedArray.java:548)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.view.View。(View.java:1850)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.view.View。(View.java:1799)

     

05-09 14:35:01.714:E / AndroidRuntime(845):在android.view.ViewGroup。(ViewGroup.java:284)

任何帮助都会很棒。

问亚历克斯

3 个答案:

答案 0 :(得分:1)

如果检查日志,看起来在unicorn.Heurazio.SettingsActivity中膨胀视图时会发生大的(~6MB)位图分配。检查您的资源,看看您是否在某处使用大位图作为背景。

答案 1 :(得分:0)

在阅读并修改我的程序之后,比如在重载的应用程序中添加对背景的引用,擦除所有不需要的上下文元素,我仍然存在同样的问题,而且看起来甚至更糟。

如果我可以相信我对位图大小的计算

Bitmap tmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.logo);
Log.d("mainApp", tmp.getRowBytes() * tmp.getHeight() / 1024 + "kB");

我的100kB徽标(.png)需要6mB ram(适用于异常消息)。任何想法都会很棒。

答案 2 :(得分:-3)

尝试在应用android:largeHeap="true"

中添加您的清单