我有一个 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() 中,但错误仍然存在。
有人知道如何解决这个问题吗?