ViewPager上的setCurrentItem调用导致应用程序因outofmemory错误而崩溃

时间:2014-03-08 10:51:25

标签: android image android-fragments

我正在尝试创建一个具有一堆低分辨率图像的应用程序(每个图像大约50 - 70 KB)。可以在图像库中滑动,或者根据某些按钮,转到库中的特定图像。我使用了FragmentStatePagerAdapter(FSPA)的ViewPager,因为我知道这是刷入图像的最佳内存最佳方式。我期待这种方法确保在任何给定的时间点只有3个图像/片段存活,因此不应该存在内存问题。这种方法适用于大多数仿真器。但是,当我尝试使用Nexus One模拟器(我使用的是Android Studio)时,我发现了一个问题。滑动部分工作正常,但如果我使用按钮转到特定页面(使用viewPager.SetCurrentItem()方法),应用程序崩溃时会出现内存错误。我需要做些什么才能使其正常工作(点击按钮转到特定图像)?

我有一个主要活动页面和两个片段页面。这是代码:

主要活动页面:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:paddingLeft="@dimen/activity_horizontal_margin"
      android:paddingRight="@dimen/activity_horizontal_margin"
      android:paddingTop="@dimen/activity_vertical_margin"
      android:paddingBottom="@dimen/activity_vertical_margin"
      tools:context="com.example.tryslider.tryslider.MainActivity">
    </RelativeLayout>

片段分页器(使用ViewPager和按钮):

        <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:background="#5b9bd5"
    android:padding="4dip" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:measureWithLargestChild="true"
        android:orientation="horizontal" >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/goButtonLabel"
            android:id="@id/goButton"
            android:textColor="#ffffff"
            android:background="@drawable/abc_ab_transparent_dark_holo" />
    </LinearLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v4.view.ViewPager>

        </LinearLayout>

包含图片的片段:

<?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="match_parent">


    <ImageView
        android:id="@id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="36dp"
        android:src="@drawable/first" />

</RelativeLayout>

这是我的主要活动代码(注意SetCurrentItem中的数字 - 我只是移动到堆栈中的任意图像,在这种情况下说第5张图像(总共10张图像中):

package com.example.tryslider.tryslider;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

import java.text.SimpleDateFormat;

public class MainActivity extends ActionBarActivity {

    static final int ITEMS = 10;
    MyAdapter viewAdapter;
    ViewPager viewPager;
    private Button goButton;

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

        viewAdapter = new MyAdapter(getSupportFragmentManager());
        viewPager = (ViewPager) findViewById(R.id.pager);
        viewPager.setAdapter(viewAdapter);

        goButton = (Button) findViewById(R.id.goButton);

        goButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                viewPager.setCurrentItem(5, false);
            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    public static class MyAdapter extends FragmentStatePagerAdapter {
        public MyAdapter(FragmentManager fragmentManager) {
            super(fragmentManager);
        }

        @Override
        public int getCount() {
            return ITEMS;
        }

        @Override
        public Fragment getItem(int position) {
            return ImageFragment.init(position);
        }

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

    }

}

图像片段代码:

package com.example.tryslider.tryslider;

/**
 * Created by rahul on 8/3/14.
 */

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;


public class ImageFragment extends Fragment {
    private int index;
    private int[] mImages = new int[] {
            R.drawable.first,
            R.drawable.second,
            R.drawable.third,
            R.drawable.fourth,
            R.drawable.fifth,
            R.drawable.sixth,
            R.drawable.seventh,
            R.drawable.eighth,
            R.drawable.ninth,
            R.drawable.tenth
    };
    static ImageFragment init(int val) {
        ImageFragment myFrag = new ImageFragment();
        Bundle args = new Bundle();
        args.putInt("val", val);
        myFrag.setArguments(args);
        return myFrag;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        index = getArguments() != null ? getArguments().getInt("val") : 1;
    }

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

        ImageView imageView = (ImageView) layoutView.findViewById(R.id.imageView);
        imageView.setImageResource(mImages[index]);

        return layoutView;
    }
}

我尝试了很多关于SO和其他方面的建议,但此刻我正在努力解决这个问题。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

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

不需要此部分。 FragmentStatePager将处理销毁和重新创建视图。