Моя проблема в основном такая: странная проблема нехватки памяти , и я подумал, что уже решил эту проблему, вызвав recycle (). Эта проблема возникает в примере в моем ListView: каждый элемент имеет от 0 до 10 значков. Я расширил свой адаптер, чтобы перерабатывать все растровые изображения из convertView, который работает.
после того, как на элемент нажали, я показываю подробный сайт, который использует те же BMP, что и мой список. Но разработка продолжается, и мне нужно показать все на вкладках. Таким образом, мой ListView и DetailView должны отображаться на одной вкладке. После двух дней борьбы с «ActivityGroup» (которая, кстати, устарела), я решил использовать пакет совместимости и начать программировать свою Activity, которая показывает List и DetailActivity как фрагменты. Кажется, что это работает, но мой ListViewAdapter перерабатывает каждый Bitmap из convertView, но он не работает на моем DetailView. Журнал говорит мне, что вызывается recycle, но после 2-3 DetailView (в зависимости от показанных растровых изображений) я получаю ту же старую ошибку.
Это мое единственное занятие, живущее внутри TabView:
public class FaultGroup extends FragmentActivity implements OnItemClickListener, OnBackStackChangedListener{
public static final String FRAGMENT_LIST_TAG = "FaultListFragment";
public static final String FRAGMENT_DETAIL_TAG = "FaultDetailFragment";
public static final String TAG = "FaultGroup";
private FragmentManager mFragmentManager;
private FragmentTransaction mTransaction;
private boolean mDetailsShown = false;
public void onCreate(Bundle icicle){
super.onCreate(icicle);
setContentView(R.layout.fragment_layout);
mFragmentManager = getSupportFragmentManager();
mFragmentManager.addOnBackStackChangedListener(this);
FaultReportListFragment fragment = new FaultReportListFragment();
mTransaction= mFragmentManager.beginTransaction();
mTransaction.add(R.id.fragment_container, fragment, FRAGMENT_LIST_TAG);
mTransaction.addToBackStack(null);
mTransaction.commit();
}
public void onResume(){
super.onResume();
LogCat.d(TAG, "onResume");
}
public void onDestroy(){
super.onDestroy();
LogCat.d(TAG, "onDestroy");
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
LogCat.d(TAG, "onItemClick");
DatabaseReport dbReport = (DatabaseReport)parent.getAdapter().getItem(position);
fiScheduleDeviationReport report = dbReport.read();
Bundle arguments = new Bundle();
arguments.putParcelable(FaultReportDetailFragment.KEY_REPORT_EXTRA, report);
FaultReportDetailFragment fragment = new FaultReportDetailFragment();
fragment.setArguments(arguments);
mDetailsShown = true;
mTransaction = mFragmentManager.beginTransaction();
mTransaction.replace(R.id.fragment_container, fragment, FRAGMENT_DETAIL_TAG);
mTransaction.addToBackStack(null);
mTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
mTransaction.commit();
}
@Override
public void onBackPressed(){
mDetailsShown = false;
super.onBackPressed();
/*
mTransaction = mFragmentManager.beginTransaction();
mTransaction.remove(mFragmentManager.findFragmentByTag(FRAGMENT_DETAIL_TAG));
mTransaction.
mTransaction.commit();
*/
}
@Override
public void onBackStackChanged() {
// TODO Auto-generated method stub
}
}
Я вижу в своем журнале, что Android вызывает onDestroyView и onDestroy для моего DetailFragment, но каким-то образом он должен хранить SOMETHING . Если я просто прокручиваю (что вызывает OOM Error, если я не перезаписываю convertViews), я не получаю ошибок. Только если я открыл детали один раз.
Вот методы, которые перерабатывают мои BMP:
ОПИСАНИЕ:
public void onDestroyView(){
LogCat.d(TAG, "onDestroyView");
LinearLayout iconRow;
for (int i = 0; i < mIconInflationArea.getChildCount(); i++){
LogCat.d(TAG, "onDestroyView-> inflationAreaChilds: " + mIconInflationArea.getChildCount());
iconRow = (LinearLayout)mIconInflationArea.getChildAt(i);
for (int row = 0; row < iconRow.getChildCount(); row++){
LogCat.d(TAG, "onDestroyView iconRow childs: " + iconRow.getChildCount());
View v = iconRow.getChildAt(row);
if (v instanceof ImageView){
ImageView image = (ImageView)v;
Drawable d = image.getDrawable();
Bitmap bmp = null;
if (d instanceof SvgDrawable){
SvgDrawable svg = (SvgDrawable)d;
bmp = svg.getBitmap();
} else if (d instanceof BitmapDrawable){
BitmapDrawable bmpd = (BitmapDrawable)d;
bmp = bmpd.getBitmap();
}
if (bmp != null){
bmp.recycle();
}
}
}
iconRow = null;
}
mIconInflationArea.removeAllViews();
mMessage = null;
//System.gc();
super.onDestroyView();
}
ADAPTER:
private void recycleBmpsFromConvertView(LinearLayout iconArea){
for (int i = 0; i < iconArea.getChildCount(); i++){
View v = iconArea.getChildAt(i);
if (v instanceof LinearLayout){
LinearLayout row = (LinearLayout)v;
for (int j = 0; j < row.getChildCount(); j++){
View candidate = row.getChildAt(j);
if (candidate instanceof ImageView){
ImageView image = (ImageView)candidate;
Drawable d = image.getDrawable();
Bitmap bmp = null;
if (d instanceof SvgDrawable){
SvgDrawable svg = (SvgDrawable)d;
bmp = svg.getBitmap();
} else if (d instanceof BitmapDrawable){
BitmapDrawable bmpd = (BitmapDrawable)d;
bmp = bmpd.getBitmap();
}
if (bmp != null){
bmp.recycle();
}
}
}
}
}
iconArea.removeAllViews();
}
Прав ли я решать эту проблему в API фрагментов или мне просто не хватает чего-то еще?
РЕДАКТИРОВАТЬ: Мне кажется, что у меня нет утечки памяти. Вот что говорит мне Лог:
09-20 17:51:34.578: DEBUG/dalvikvm(11394): GC_EXPLICIT freed 54K, 48% free 4600K/8839K, external 12673K/13427K, paused 93ms
09-20 17:51:54.906: DEBUG/dalvikvm(7904): GC_CONCURRENT freed 608K, 57% free 2902K/6599K, external 1625K/2137K, paused 2ms+7ms
09-20 17:52:00.316: DEBUG/dalvikvm(9634): GC_CONCURRENT freed 550K, 51% free 3242K/6599K, external 1625K/2137K, paused 2ms+7ms
09-20 17:52:12.574: DEBUG/dalvikvm(9634): GC_EXPLICIT freed 352K, 55% free 2998K/6599K, external 1625K/2137K, paused 60ms
09-20 17:52:19.601: DEBUG/dalvikvm(8082): GC_EXPLICIT freed 347K, 53% free 3086K/6535K, external 1625K/2137K, paused 61ms
09-20 17:52:24.609: DEBUG/dalvikvm(7904): GC_EXPLICIT freed 247K, 56% free 2947K/6599K, external 1625K/2137K, paused 64ms
09-20 17:52:53.410: DEBUG/dalvikvm(10578): GC_CONCURRENT freed 540K, 56% free 3007K/6727K, external 1625K/2137K, paused 2ms+9ms
09-20 17:53:05.523: DEBUG/dalvikvm(7904): GC_CONCURRENT freed 591K, 56% free 2952K/6599K, external 1625K/2137K, paused 15ms+2ms
09-20 17:53:35.156: DEBUG/dalvikvm(7904): GC_EXPLICIT freed 259K, 57% free 2895K/6599K, external 1625K/2137K, paused 74ms
09-20 17:53:54.378: DEBUG/dalvikvm(10578): GC_CONCURRENT freed 538K, 56% free 3005K/6727K, external 1625K/2137K, paused 2ms+10ms
09-20 17:54:00.242: DEBUG/dalvikvm(9634): GC_CONCURRENT freed 350K, 52% free 3217K/6599K, external 1625K/2137K, paused 1ms+3ms
09-20 17:54:05.378: DEBUG/dalvikvm(9634): GC_EXPLICIT freed 360K, 55% free 3018K/6599K, external 1625K/2137K, paused 53ms
09-20 17:54:14.785: DEBUG/dalvikvm(8082): GC_EXPLICIT freed 216K, 53% free 3086K/6535K, external 1625K/2137K, paused 58ms
09-20 17:54:16.171: DEBUG/dalvikvm(7904): GC_CONCURRENT freed 574K, 57% free 2899K/6599K, external 1625K/2137K, paused 14ms+2ms