在循环中添加自定义视图会导致内存不足错误

时间:2013-09-06 17:15:03

标签: android memory-leaks out-of-memory

我正在尝试从xml多次添加自定义视图到Android活动中的另一个视图。但是,在打开和关闭该活动几次后,它会导致内存不足错误。这是代码:

ImageLoader imageLoader = new ImageLoader(currentActivity.getApplicationContext());
FlowLayout postsLayout = (FlowLayout) findViewById(R.id.tab_posts);
postsLayout.removeAllViews();

for (final Post post : postsData) {



                RelativeLayout profilePostItem = (RelativeLayout) View.inflate(this, R.layout.drawer_item, null);
                ImageView postPic = (ImageView) profilePostItem.findViewById(R.id.post_pic);

                String picUrl = post.getSingleImageURL();

                if(picUrl != null && !picUrl.equals("null"))
                {
                    postPic.setTag(picUrl);
                    imageLoader.DisplayImage(picUrl, currentActivity, postPic, R.drawable.default_item);

                }



                profilePostItem.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View view) {
                        Intent intent = new Intent(currentActivity, PostDetailsActivity.class);
                        intent.putExtra("postID", Integer.toString(post.getPostId()));
                        currentActivity.startActivity(intent);
                    }
                });

                postsLayout.addView(profilePostItem);

            }

这里是drawer_item.xml

<?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"              
                android:layout_width="match_parent"
                android:layout_height="wrap_content"

                >


<ImageView 
        android:id="@+id/post_pic"
        android:layout_width="140dp"
        android:layout_height="140dp"       
        android:background="#FFFFFF" 
        android:src="@drawable/default_user_pic"
    />   


</RelativeLayout>

这是LogCat输出:

    09-06 22:32:45.566: D/dalvikvm(11857): GC_BEFORE_OOM freed <1K, 6% free 46549K/49095K, paused 67ms, total 67ms
09-06 22:32:45.566: E/dalvikvm-heap(11857): Out of memory on a 67816-byte allocation.
09-06 22:32:45.566: I/dalvikvm(11857): "Thread-15875" prio=4 tid=53 RUNNABLE
09-06 22:32:45.566: I/dalvikvm(11857):   | group="main" sCount=0 dsCount=0 obj=0x4325e6d8 self=0x53269790
09-06 22:32:45.566: I/dalvikvm(11857):   | sysTid=12239 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1395039200
09-06 22:32:45.566: I/dalvikvm(11857):   | schedstat=( 124808833 28013003 46 ) utm=10 stm=1 core=1
09-06 22:32:45.566: I/dalvikvm(11857):   at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
09-06 22:32:45.566: I/dalvikvm(11857):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:652)
09-06 22:32:45.566: I/dalvikvm(11857):   at com.company.testapp.utils.ImageLoader.decodeFile(ImageLoader.java:139)
09-06 22:32:45.566: I/dalvikvm(11857):   at com.company.testapp.utils.ImageLoader.getBitmap(ImageLoader.java:81)
09-06 22:32:45.566: I/dalvikvm(11857):   at com.company.testapp.utils.ImageLoader.access$0(ImageLoader.java:73)
09-06 22:32:45.566: I/dalvikvm(11857):   at com.company.testapp.utils.ImageLoader$PhotosLoader.run(ImageLoader.java:196)
09-06 22:32:45.566: D/skia(11857): --- decoder->decode returned false
09-06 22:32:45.566: W/dalvikvm(11857): threadid=53: thread exiting with uncaught exception (group=0x41aee2a0)
09-06 22:32:45.566: E/AndroidRuntime(11857): FATAL EXCEPTION: Thread-15875
09-06 22:32:45.566: E/AndroidRuntime(11857): java.lang.OutOfMemoryError
09-06 22:32:45.566: E/AndroidRuntime(11857):    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
09-06 22:32:45.566: E/AndroidRuntime(11857):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:652)
09-06 22:32:45.566: E/AndroidRuntime(11857):    at com.company.testapp.utils.ImageLoader.decodeFile(ImageLoader.java:139)
09-06 22:32:45.566: E/AndroidRuntime(11857):    at com.company.testapp.utils.ImageLoader.getBitmap(ImageLoader.java:81)
09-06 22:32:45.566: E/AndroidRuntime(11857):    at com.company.testapp.utils.ImageLoader.access$0(ImageLoader.java:73)
09-06 22:32:45.566: E/AndroidRuntime(11857):    at com.company.testapp.utils.ImageLoader$PhotosLoader.run(ImageLoader.java:196)
09-06 22:32:45.651: I/dalvikvm-heap(11857): Clamp target GC heap from 48.757MB to 48.000MB
09-06 22:32:45.651: D/dalvikvm(11857): GC_FOR_ALLOC freed 180K, 6% free 46583K/49159K, paused 68ms, total 68ms
09-06 22:32:45.651: I/dalvikvm-heap(11857): Forcing collection of SoftReferences for 63616-byte allocation
09-06 22:32:45.736: I/dalvikvm-heap(11857): Clamp target GC heap from 48.757MB to 48.000MB
09-06 22:32:45.736: D/dalvikvm(11857): GC_BEFORE_OOM freed 0K, 6% free 46583K/49159K, paused 82ms, total 82ms
09-06 22:32:45.736: E/dalvikvm-heap(11857): Out of memory on a 63616-byte allocation.
09-06 22:32:45.736: I/dalvikvm(11857): "Thread-15874" prio=4 tid=49 RUNNABLE

任何人都能说出它为什么会泄漏记忆吗?

2 个答案:

答案 0 :(得分:2)

它是known bug,这不是因为大文件。由于Android缓存Drawables,因此在使用少量图像后内存不足。但我通过跳过Android默认缓存系统找到了它的替代方式。

<强> Soultion : 在Assets中创建一个drawable文件夹,并将图像移动到资源中的“drawable”文件夹,并使用以下函数获取BitmapDrawable

public static Drawable getAssetImage(Context context, String filename) throws IOException {
    AssetManager assets = context.getResources().getAssets();
    InputStream buffer = new BufferedInputStream((assets.open("drawable/" + filename + ".png")));
    Bitmap bitmap = BitmapFactory.decodeStream(buffer);
    return new BitmapDrawable(context.getResources(), bitmap);
}

参考:https://stackoverflow.com/posts/6116316/revisions

答案 1 :(得分:0)

我已使用Universal Image Loader替换我的ImageLoader解决了这个问题。