0

我有一个 viewpager 并使用 FragmentPagerAdapter 来管理 3 个片段。在其中一个片段中,我有一个包含图像的 ListView。当我在每个片段之间滑动时,我最终会得到(从 frag1 到 frag3 大约 20 次滑动之后)OutOfmemoryException,我将在下面包含 logcat,似乎是 Bitmap/ImageViews 是导致触发内存不足异常的错误的原因。在我的 ListAdapter 中,我使用 convertview 来回收位图。

这是我的片段活动:

public class MainActivity extends SherlockFragmentActivity implements
        ActionBar.TabListener {

    SectionsPagerAdapter mSectionsPagerAdapter;
    ViewPager mViewPager;
    SimpleDateFormat sdf;

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

        final ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        mSectionsPagerAdapter = new SectionsPagerAdapter(
                getSupportFragmentManager());

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        actionBar.setSelectedNavigationItem(position);
                    }
                });

        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {

            actionBar.addTab(actionBar.newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(i))
                    .setTabListener(this));
        }

    }

    public class SectionsPagerAdapter extends FragmentPagerAdapter {

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

        @Override
        public Fragment getItem(int position) {

            Fragment fragment = null;

            if (position == 0) {

                fragment = new BrowseVidsFragment();
                Bundle args = new Bundle();
                args.putInt(BrowseVidsFragment.ARG_SECTION_NUMBER, position + 1);
                fragment.setArguments(args);
            }
            if (position == 1) {
                fragment = new RecordTodaysVidFragment();
                Bundle args = new Bundle();
                args.putInt(RecordTodaysVidFragment.ARG_SECTION_NUMBER,
                        position + 1);
                fragment.setArguments(args);
            }
            if (position == 2) {
                fragment = new CompleteVidFragment();

            }

            return fragment;
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
            case 0:
                return getString(R.string.title_section1).toUpperCase();
            case 1:
                return getString(R.string.title_section2).toUpperCase();
            case 2:
                return getString(R.string.title_section3).toUpperCase();
            }
            db = new DBAdapter(MainActivity.this);
            return null;
        }
    }

    @Override
    public void onResume() {
        super.onResume();

        Log.d("", "MainActiity onResume()");

    }
}

这是包含 ListView 的 Fragment 类,其中包含 ImageViews

public class BrowseVidsFragment extends Fragment {

    ListView yearsLv, monthsLv, lv;
    VidsObject vidsobj;
    Spinner spinner1;
    TheListAdapter adapter;
    ArrayList<String> thumbsToShow;
    ArrayList<String> vidsToShow;
    ArrayList<String> uniqueMonths;
    ArrayList<String> captions;
    String selectedYear = "";
    String selectedMonth = "";
    MyVideoFragment myFragment;
    int currentVid = 0;
    DBAdapter db;

    public static final String ARG_SECTION_NUMBER = "section_number";

    public BrowseVidsFragment() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View myFragmentView = inflater.inflate(R.layout.browsevidsfragment,
                container, false);
        try {

            FragmentTransaction fragmentTransaction = getActivity()
                    .getSupportFragmentManager().beginTransaction();

            myFragment = new MyVideoFragment();
            fragmentTransaction.add(R.id.myfragment, myFragment);
            fragmentTransaction.commit();
            lv = (ListView) myFragmentView.findViewById(R.id.list);

        } catch (Exception ex) {
            ex.getMessage().toString();
        }

        return myFragmentView;
    }


    @Override
    public void onResume() {
        super.onResume();

        setLists();

    }

    public void setLists() {

        selectedYear = getCurrentYear();
        selectedMonth = getCurrentMonth();

        db = new DBAdapter(getActivity());

        Toast.makeText(getActivity(), "on resume", 2000).show();
        File dir = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/");

        final String[] vids = dir.list(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(".mp4") && !name.contains("temp");

            }
        });

        ArrayList<String> vidslist = new ArrayList<String>();
        Arrays.sort(vids);

        for (String s : vids) {

            String noExtension = s.substring(0, s.length() - 4);
            vidslist.add(noExtension + ".jpg");
            Log.d("", "added: " + noExtension + ".jpg");
        }
        captions = new ArrayList<String>();
        db.open();

        Cursor c = db.getCaptions();
        if (c.moveToFirst()) {
            while (c.isAfterLast() == false) {
                captions.add(c.getString(0));
                c.moveToNext();
            }
        }
        c.close();
        db.close();
        Collections.reverse(captions);

        vidsobj = new VidsObject(new ArrayList(Arrays.asList(vids)));
        vidsToShow = vidsobj.getAllVids(false);
        thumbsToShow = vidsobj.getAllVids(true);
        Collections.reverse(vidsToShow);
        Collections.reverse(thumbsToShow);

        adapter = new TheListAdapter(getActivity(),
                vidsToShow.toArray(new String[vidsToShow.size()]),
                thumbsToShow.toArray(new String[thumbsToShow.size()]),
                captions.toArray(new String[captions.size()]));

        lv.setAdapter(adapter);

        lv.setOnItemClickListener(new OnItemClickListener() {

            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                myFragment.setVid(String.valueOf(vidsToShow.get(position)
                        + ".mp4"));
                currentVid = position;

            }

        });

    }


    public String getCurrentYear() {

        Calendar now = Calendar.getInstance();
        return String.valueOf(now.get(Calendar.YEAR));
    }

    public String getCurrentMonth() {

        Calendar now = Calendar.getInstance();
        return String.valueOf(now.get(Calendar.MONTH));
    }

    @Override
    public void onPause() {
        super.onPause();
        Toast.makeText(getActivity(), "onPause()", 200).show();

    }

}

这是发生错误时的Logcat

01-26 14:49:52.409: E/AndroidRuntime(21281): java.lang.OutOfMemoryError 01-26 14:49:52.409: E/AndroidRuntime(21281): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 01 -26 14:49:52.409: E/AndroidRuntime(21281): 在 android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529) 01-26 14:49:52.409: E/AndroidRuntime(21281): 在 android.graphics .BitmapFactory.decodeFile(BitmapFactory.java:302) 01-26 14:49:52.409: E/AndroidRuntime(21281): 在 android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:328) 01-26 14:49:52.409 : E/AndroidRuntime(21281): 在 android.graphics.drawable.Drawable.createFromPath(Drawable.java:898) 01-26 14:49:52.409: E/AndroidRuntime(21281): 在 android.widget.ImageView.resolveUri( ImageView.java:643) 01-26 14:49:52.409: E/AndroidRuntime(21281): 在 android.widget。ImageView.setImageURI(ImageView.java:381) 01-26 14:49:52.409: E/AndroidRuntime(21281): 在 com.example.myapp.TheListAdapter.getView(TheListAdapter.java:80) 01-26 14:49: 52.409: E/AndroidRuntime(21281): 在 android.widget.AbsListView.obtainView(AbsListView.java:2159) 01-26 14:49:52.409: E/AndroidRuntime(21281): 在 android.widget.ListView.makeAndAddView(ListView .java:1831) 等等

为了尝试阻止 OutOfMemoryError 的发生,我将 System.gc() 添加到 Fragment 类的 onPause() 中,但错误仍然存​​在。

有人知道如何解决这个问题吗?

4

1 回答 1

1

检查本指南:http: //developer.android.com/training/displaying-bitmaps/load-bitmap.html

您可以使用 BitmapFactory.Options inSampleSize 加载较小的图像并避免 OutOfMemoryError。

于 2013-01-25T15:55:03.107 回答