Android:从已完成的活动中释放内存不起作用

时间:2014-08-12 16:36:05

标签: android memory-leaks

我有一些带有一些图像和一些按钮的活动。当我点击其中一个按钮时,我想用其他一些图像打开相同的活动。问题是,当我启动活动的新副本时,前一个活动的内存不会被释放。在按钮的OnClickListener上,我尝试了清除内存缓存并销毁imageviews以及OnDestroy方法,但没有结果。我尝试了Volley,Picasso,Universal Image Loader和其他一些用于缓存图像的库,并且在一些活动调用之后我得到了OutOfMemory Exception。我看到MAT并且在活动的每次调用中,堆上先前存储的bitmans仍然存在。只有当我按下后退按钮时才释放。我还尝试使用新图像更新当前活动,但仍然存在泄漏并且旧数据存储在内存中。知道如何防止内存泄漏吗?我很抱歉,如果这个问题看起来很愚蠢,但我已经尝试了4天没有任何结果来解决这个问题。

Activity.java

public void updateLayout(){
    bar.setVisibility(View.GONE);
    rl.setVisibility(View.VISIBLE);
    ScrollView sc = (ScrollView) act.findViewById(R.id.scrollView1);
    sc.fullScroll(ScrollView.FOCUS_UP);

    LinePageIndicator mIndicator = (LinePageIndicator)findViewById(R.id.indicator);

    viewPager = (ViewPager) findViewById(R.id.pagerImg);
    ImageProductAdapter adapter = new ImageProductAdapter(ProductActivity.this,item.getImageUrls(), item);
    viewPager.setAdapter(adapter);
    viewPager.setCurrentItem(0);

    mIndicator.getLayoutParams().height = mIndicator.getHeight() + 2;
    mIndicator.setViewPager(viewPager);


    if(!item.getRelatedItems().isEmpty()){

        GridLayout grid = (GridLayout) this.findViewById(R.id.grid1);
        grid.setVisibility(View.VISIBLE);
        grid.removeAllViews();

        for(int i = 0; i < item.getRelatedItems().size(); i++) {
            final int j = i;
            ImageView v = new ImageView(this);
            DisplayImageOptions options = new DisplayImageOptions.Builder()
                    .showImageOnLoading(R.drawable.no_image)
                    .showImageForEmptyUri(R.drawable.no_image)
                    .showImageOnFail(R.drawable.no_image)
                    .cacheInMemory(true)
                    .cacheOnDisk(true)
                    .considerExifParams(true)
                    .bitmapConfig(Bitmap.Config.RGB_565)
                    .imageScaleType(ImageScaleType.EXACTLY)
                    .build();

            ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(act.getApplicationContext()).build();
            com.nostra13.universalimageloader.core.ImageLoader.getInstance().init(config);
            com.nostra13.universalimageloader.core.ImageLoader imageLoader = com.nostra13.universalimageloader.core.ImageLoader.getInstance();


            grid.addView(v);
            v.getLayoutParams().height = 100;
            v.getLayoutParams().width = 100;

            imageLoader.displayImage(item.getRelatedItems().get(i).getImageUrl(), v, options);

            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Intent activity = new Intent(ProductActivity.this,ProductActivity.class);
                    activity.putExtra("id", item.getRelatedItems().get(j).getProductID());
                    activity.putExtra("title", item.getRelatedItems().get(j).getTitle());
                    startActivity(activity);
                    act.finish();
                    }




            });
        }



    }

}

1 个答案:

答案 0 :(得分:0)

问题在于,由于默认行为是针对新活动的后退按钮指向它所产生的活动,因此该链接会将所有旧活动保留在内存中,并且不会进行垃圾回收。您需要删除该行为,然后您的旧活动将被正确地垃圾收集。

这就是为什么当您按下后退按钮时,会释放最新的活动:没有任何内容正在引用它。

第一项活动 - &gt;(产生新活动) - &gt;第二项活动 - &gt; (产生新活动) - &gt;第三项活动

第三个活动的后退按钮引用第二个,第二个引用第一个。如果你回击第三个活动,它的实例将被垃圾收集,因为第二个活动中没有任何内容链接回它。

正如Squonk在评论中指出的那样,你应该在下一个活动启动之前调用finish()来清理活动并防止这种行为。