我有一个viewpager并使用FragmentPagerAdapter来管理3个片段。在其中一个片段中,我有一个ListView,用于保存图像。当我在每个片段之间滑动时,我最终会得到(在从frag1到frag3的大约20次刷卡之后)OutOfmemoryException,我将在下面包含logcat,似乎是Bitmap / ImageViews是导致错误的原因,它触发了outofmemory异常。在我的ListAdapter中,我使用convertview来回收位图。
这是我的FragmentActivity:
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()");
}
}
这是Fragment类,它包含ListView,其中包含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):at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529) 01-26 14:49:52.409:E / AndroidRuntime(21281):at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:302) 01-26 14:49:52.409:E / AndroidRuntime(21281):at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:328) 01-26 14:49:52.409:E / AndroidRuntime(21281):at android.graphics.drawable.Drawable.createFromPath(Drawable.java:898) 01-26 14:49:52.409:E / AndroidRuntime(21281):at android.widget.ImageView.resolveUri(ImageView.java:643)01-26 14:49:52.409:E / AndroidRuntime(21281):at android.widget.ImageView.setImageURI(ImageView.java:381)01-26 14:49:52.409:E / AndroidRuntime(21281):at com.example.myapp.TheListAdapter.getView(TheListAdapter.java:80)01-26 14:49:52.409:E / AndroidRuntime(21281):at android.widget.AbsListView.obtainView(AbsListView.java:2159)01-26 14:49:52.409:E / AndroidRuntime(21281):at android.widget.ListView.makeAndAddView(ListView.java:1831) 等等 等
为了尝试阻止OutOfMemoryError的发生我将System.gc()添加到Fragment类的onPause(),但错误仍然存在。
任何人都有想法如何解决这个问题?
答案 0 :(得分:1)
查看本指南: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
您可以使用inSampleSize中的BitmapFactory.Options来加载较小的图像并避免OutOfMemoryError。