gpt4 book ai didi

android - Fragment 中的 Listview 导致内存泄漏

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:58:07 30 4
gpt4 key购买 nike

我有一个带有 FragmentMediaOverview 的 FragmentActivity,其中包含一个 MediaItemView 列表(每个都有一个 imageview 和一些文本),然后单击其中一个项目打开详细信息-分段。现在,当我从列表返回(通过后退按钮)并来回(单击列表项)多次到详细信息 fragment 时,我最终遇到了 OOM-Errors。我对列表项和细节 fragment 中的位图使用 SoftReference。根据 MA​​T,MediaItemViewFragmentMediaOverview 实例的数量在增加,但我就是不明白为什么。

我读了这个Android: AlertDialog causes a memory leak , 但无法解决 null 听众。

这是我的代码:

FragmentMediaOverview.java

(这不是 ListFragment,因为对于平板电脑布局,MediaAdapter 需要连接到 gridview)

public class FragmentMediaOverview extends Fragment {
private static String TAG = FragmentMediaOverview.class.getSimpleName();

private MediaAdapter adapter;
private OnMediaSelectedListener selListener;
private ArrayList<BOObject> mediaItems;

private ViewGroup layoutContainer;
private AdapterView itemContainer; // list or gridview

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
layoutContainer = (ViewGroup) inflater.inflate(R.layout.fragment_media_overview, null);

return layoutContainer;
}

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
selListener = (OnMediaSelectedListener) activity;
}

@Override
public void onDestroy() {
super.onDestroy();
itemContainer.setOnItemClickListener(null);
selListener = null;
adapter = null;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initUi(layoutContainer);
displayMedia();
}

private void initUi(ViewGroup layoutContainer) {
itemContainer = (AdapterView) layoutContainer.findViewById(android.R.id.list);
itemContainer.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
BOMedia mediaItem = ((BOMedia) mediaItems.get(position));
//the FragmentActivity is coordinating the FragmentTransactions
selListener.onMediaSelected(mediaItem);
}
});
}

private void displayMedia() {
Log.d(TAG, "Displaying List");
if (mediaItems == null) {
loadMedia();
return;
}

Log.d(TAG, "List: " + mediaItems.size() + ", adapter: " + itemContainer.getAdapter());

if (adapter == null) {
Log.d(TAG, "Create Adapter with " + mediaItems.size());

adapter = new MediaAdapter(getActivity(), mediaItems);
}

if (itemContainer.getAdapter() == null) {
itemContainer.setAdapter(adapter);
} else {
adapter.setItems(mediaItems);
adapter.notifyDataSetChanged();
}

}

private void loadMedia() {
FragmentHelper.showProgressSpinner(layoutContainer, android.R.id.list);
DbHelper.getInstance().getMedia(mediaType, new DbQueryFinishListener() {

@Override
public void onDbCallFinish(ArrayList<BOObject> objects) {
if (!getActivity().isFinishing()) {
mediaItems = objects;
Collections.sort(mediaItems, new Comparator<BOObject>() {
final Collator c = Collator.getInstance(Locale.GERMAN);
@Override
public int compare(BOObject s1, BOObject s2) {
if (s2 != null && ((BOMedia) s2).getTitle() != null && s1 != null
&& ((BOMedia) s1).getTitle() != null) {
return c.compare(((BOMedia) s1).getTitle(),((BOMedia) s2).getTitle());
} else {
return 0;
}
}
});
displayMedia();
FragmentHelper.hideProgressSpinner(layoutContainer, android.R.id.list);
}
}

@Override
public void onDbCallException(Exception exception) {
if (!getActivity().isFinishing()) {
FragmentHelper.hideProgressSpinner(layoutContainer, android.R.id.list);
}
}
});

}
}

媒体适配器.java

public class MediaAdapter extends BaseAdapter {
private static final String TAG = MediaAdapter.class.getSimpleName();
private Context context;
private ArrayList<BOObject> mediaItems;

public MediaAdapter(Context c, ArrayList<BOObject> mediaItems) {
super();
context = c;
this.mediaItems = mediaItems;
}

@Override
public int getCount() {
return mediaItems.size();
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = new MediaItemView(context);
}
((MediaItemView)convertView).initialize((BOMedia) mediaItems.get(position));
return convertView;
}

public void setItems(ArrayList<BOObject> mediaItems) {
this.mediaItems = mediaItems;
}
}

MediaItemView.java

public class MediaItemView extends LinearLayout {
private static final String TAG = MediaItemView.class.getSimpleName();
private BOMedia item;
private SoftReference<Bitmap> bm;
private ImageView iv;
private Context ctx;

public MediaItemView(Context context) {
super(context);
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(R.layout.view_media_item, this);
this.ctx = context;
}

/** Init the view with a new BOMedia object
* @param mediaItem
*/
public void initialize(BOMedia mediaItem) {
this.item = mediaItem;
initUI();
}

private void initUI() {
TextView title = (TextView) findViewById(R.id.itemText);
iv = (ImageView) findViewById(R.id.itemImage);

title.setText(Html.fromHtml(item.getTitle()));
iv.setImageBitmap(null);
bm = null;
System.gc();
iv.invalidate();
if (item.getFilepathThumb() != null && !item.getFilepathThumb().equals("")) {

ExpansionPackManager.getInstance().getBitmapResource(item.getFilepathThumb(), false,
new BitmapReadListener() {

@Override
public void onFileRead(BitmapResponseMessage message) {
Log.d(TAG, "Bitmap read: " + message.getFilepath());
Bitmap image = message.getBitmap();
if (image != null && message.getFilepath().equals(item.getFilepathThumb())) {
bm = new SoftReference<Bitmap>(image);
iv.setImageBitmap(bm.get());
Log.d(TAG, "image set");
} else {
Log.d(TAG, "image too late: " + image);
}
}

@Override
public void onFileException(Throwable exception) {
Log.d(TAG, "image exception");
}
});

}
}

}

最佳答案

在 MediaItemView 中,位图的大小一定太大了。如果位图为 600x600,而您想要显示尺寸为 50x50 的图像,则可以使用 Bitmap.createScaledBitmap。您还应该在加载位图时使用位图缓存。

关于android - Fragment 中的 Listview 导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11228239/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com