带有imageview的viewpager中的OutOfMemory问题

时间:2013-09-15 15:09:04

标签: android android-fragments android-viewpager out-of-memory universal-image-loader

我有一个内存泄漏(我猜?),在我的应用程序的某个地方。我真的不知道在哪里,我一直在尝试按照几个链接解释不同的方法来关闭OOM错误,但没有运气。

问题是,我有一个209页的viewpager(动态加载数据,所有209页使用相同的单个片段)

在我开始出现任何内存错误之前,我可以滚动大约20页左右。 所有图像都由Universal-Image-Loader加载,仅缓存在光盘上,而不是缓存在内存中。

我正在使用FragmentStatePagerAdapter。

继承代码,我真的希望你们能找到我不能找到的东西..另外,如果你发现任何应该有所不同的东西,可以进行优化或任何事情,请告诉我们。 :

的活动:

public class MovieInfo extends SherlockFragmentActivity{

    MyAdapter mAdapter;
    ViewPager mPager;
    static ArrayList<Movie> items;

    public static class MyAdapter extends FragmentStatePagerAdapter {


        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public void destroyItem(View collection, int position, Object o) {
            View view = (View)o;
            ((ViewPager) collection).removeView(view);
            view = null;
        }

        @Override
        public int getCount() {
            return items.size();
        }

        @Override
        public Fragment getItem(int position) {
            Fragment f = new MovieInfoFragment();
            Bundle args = new Bundle();
            args.putParcelable("item", items.get(position));
            f.setArguments(args); 
            return f;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.movie_info_pager);


        int mIndex = getIntent().getExtras().getInt("index", 0);
        DataBaseHelper db = new DataBaseHelper(this);
        items = (ArrayList<Movie>) db.getAllMovies();
        db.close();



        mAdapter = new MyAdapter(getSupportFragmentManager());

        mPager = (ViewPager)findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);
        mPager.setCurrentItem(mIndex);
    }
}

片段:

public class MovieInfoFragment extends SherlockFragment{


    private boolean clearArt = true;
    private DisplayImageOptions options;
    private Movie movie;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle data = getArguments();
        movie = data.getParcelable("item");

        options = new DisplayImageOptions.Builder()
        .cacheOnDisc()
        .resetViewBeforeLoading()
        .bitmapConfig(Bitmap.Config.RGB_565)
        .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
        .build();

    }



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.movie_info, container, false);

        if(movie != null){

            final ImageView clearArtID = (ImageView) view.findViewById(R.id.Movie_InfoClearArt);
            final TextView title = (TextView) view.findViewById(R.id.Movie_InfoTitle);
            final TextView genre = (TextView) view.findViewById(R.id.Movie_InfoGenre);

            if(clearArt && movie.getClearArt() != null){
                clearArtID.setVisibility(ImageView.VISIBLE);
                title.setVisibility(TextView.GONE);
                genre.setVisibility(TextView.GONE);
            }else{
                clearArtID.setVisibility(ImageView.GONE);
                title.setVisibility(TextView.VISIBLE);
                genre.setVisibility(TextView.VISIBLE);
            }

            ImageView fanart = (ImageView) view.findViewById(R.id.Movie_InfoFanart);
            ImageLoader.getInstance().displayImage(movie.getFanart(), fanart, options);
            final TextView lineone = (TextView) view.findViewById(R.id.Movie_InfoLineOneText);
            final TextView linetwo = (TextView) view.findViewById(R.id.Movie_InfoLineTwoText);
            final ImageView cover = (ImageView) view.findViewById(R.id.Movie_InfoCover);
            final Movie mov = movie;
            ImageLoader.getInstance().displayImage(movie.getThumb(), cover, options);
            if(clearArt && movie.getClearArt() != null){
                ImageLoader.getInstance().displayImage(movie.getClearArt(), clearArtID, options, new ImageLoadingListener() {
                    @Override
                    public void onLoadingStarted(String imageUri, View view) { }    

                    @Override
                    public void onLoadingFailed(String imageUri, View view,
                            FailReason failReason) {
                        clearArtID.setVisibility(ImageView.GONE);
                        title.setVisibility(TextView.VISIBLE);
                        genre.setVisibility(TextView.VISIBLE);
                        title.setText(mov.getTitle().toUpperCase(Locale.ENGLISH));
                        genre.setText(mov.getGenreString());
                        lineone.setText(String.valueOf(mov.getDirectorString()));
                        linetwo.setText("WRITER");
                    }

                    @Override
                    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { }

                    @Override
                    public void onLoadingCancelled(String imageUri, View view) { }
                });
                lineone.setText(movie.getGenreString());
                linetwo.setText(movie.getDirectorString());
            }else{
                title.setText(movie.getTitle().toUpperCase(Locale.ENGLISH));
                genre.setText(movie.getGenreString());
                lineone.setText(String.valueOf(movie.getDirectorString()));
                linetwo.setText("WRITER");
            }
            TextView rating = (TextView) view.findViewById(R.id.Movie_InfoRating);
            rating.setText(movie.getRating() + " / 10");
            TextView runtime = (TextView) view.findViewById(R.id.Movie_InfoRuntime);
            runtime.setText(movie.getPlaytime()/60 + " min");
            TextView year = (TextView) view.findViewById(R.id.Movie_InfoYear);
            year.setText(String.valueOf(movie.getYear()));

            HorizontalListView listview = (HorizontalListView) view.findViewById(R.id.Movie_InfoActorList);  
            listview.setAdapter(mAdapter);  

            TextView plot = (TextView) view.findViewById(R.id.Movie_InfoPlot);
            plot.setText(movie.getPlot());

            if(movie.getCdart() != null){
                ImageView cdArt = (ImageView) view.findViewById(R.id.Movie_InfoCD);
                ImageLoader.getInstance().displayImage(movie.getCdart(), cdArt, options);
            }
        }
        return view;
    }
}

修改

我知道,我的应用程序出现OutOfMemory错误的原因是,它没有在我的大型viewpager中发布垃圾收集的位图,但是如何让我的应用程序释放它们? (读:垃圾收集)当当前不在视图中时,单个前一个或单个下一个“幻灯片”?

任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:0)

您可能应该调用destroyItem方法的超级实现