【问题标题】:OutOfMemory error with Bitmap factory and View in ListAdapter位图工厂和 ListAdapter 中的视图出现 OutOfMemory 错误
【发布时间】:2014-08-14 08:15:39
【问题描述】:

我的代码遇到错误,java.lang.OutOfMemory at

xxx.adapter.FeedListAdapter.getImageBitmap(FeedListAdapter.java)xxx.adapter.FeedListAdapter.getView(FeedListAdapter.java) 用于代码中的以下行:

mholder.imgImageView.setImageBitmap(getImageBitMap(mfeeds.getImageByte()));
return (_imagebyte==null?null:BitmapFactory.decodeByteArray(_imagebyte, 0, _imagebyte.length));

带有行的整个类遇到错误:

public class FeedsListAdapter extends BaseAdapter {
private Context mContext;
private List<SportFeed> mFeedsModels;

public FeedsListAdapter(Context context,List<SportFeed> list) {
    this.mContext = context;
    this.mFeedsModels = list;
}

private class ViewHolder{
    FrameLayout imgLayout;
    ImageView imgImageView;
    TextView txtTitle;
    TextView txtDesc; 
    TextView txtDateTime;
    LinearLayout ly_content;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder mholder = null;
    LayoutInflater minflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if(convertView == null){ 
        convertView = minflater.inflate(R.layout.feeds_listing_row, null);
        mholder = new ViewHolder();
        mholder.ly_content = (LinearLayout)convertView.findViewById(R.id.flr_content_layout);
        mholder.imgLayout = (FrameLayout)convertView.findViewById(R.id.flr_img_layout);
        mholder.imgImageView = (ImageView)convertView.findViewById(R.id.flr_img);
        mholder.txtTitle = (TextView)convertView.findViewById(R.id.flr_textTitle);
        mholder.txtDesc = (TextView)convertView.findViewById(R.id.flr_desc);
        mholder.txtDateTime = (TextView)convertView.findViewById(R.id.flr_datetime);

    }else{
        mholder = (ViewHolder)convertView.getTag();
    }

    SportFeed mfeeds = (SportFeed)getItem(position);
    mholder.txtTitle.setText(mfeeds.getTitle());
    String shortDesc = mfeeds.getContentString();
    mholder.txtDesc.setText((shortDesc.length()>0?mfeeds.getContentString():""));
    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)mholder.ly_content.getLayoutParams();
    if(mfeeds.getImageUrl().trim().equals("")){
        mholder.imgLayout.setVisibility(View.GONE);
        params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
    }else{
        mholder.imgLayout.setVisibility(View.VISIBLE);
---->   mholder.imgImageView.setImageBitmap(getImageBitMap(mfeeds.getImageByte())); //this line hits error
        params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
    }
    mholder.txtDateTime.setText(StringUtils.postDateStringConverter(mContext,mfeeds.getPostDate()));
    return convertView;
}

private Bitmap getImageBitMap(byte[] _imagebyte){

----> return (_imagebyte==null?null:BitmapFactory.decodeByteArray(_imagebyte, 0, _imagebyte.length)); //this line hits error
}

LogCat:

08-14 03:00:40.384: E/AndroidRuntime(1506): FATAL EXCEPTION: main
08-14 03:00:40.384: E/AndroidRuntime(1506): Process: org.diebao.rbbb, PID: 1506
08-14 03:00:40.384: E/AndroidRuntime(1506): java.lang.OutOfMemoryError
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:500)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:523)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at org.diebao.rbbb.adapter.FeedsListAdapter.getImageBitMap(FeedsListAdapter.java:84)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at org.diebao.rbbb.adapter.FeedsListAdapter.getView(FeedsListAdapter.java:74)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.AbsListView.obtainView(AbsListView.java:2240)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1263)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.ListView.onMeasure(ListView.java:1175)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.View.measure(View.java:16497)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)            
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) 
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.View.measure(View.java:16497)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.View.measure(View.java:16497)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.View.measure(View.java:16497)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:327)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.View.measure(View.java:16497)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.View.measure(View.java:16497)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1916)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1113)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1295)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.Choreographer.doCallbacks(Choreographer.java:574)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.Choreographer.doFrame(Choreographer.java:544)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.os.Handler.handleCallback(Handler.java:733)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.os.Handler.dispatchMessage(Handler.java:95)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.os.Looper.loop(Looper.java:136)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at android.app.ActivityThread.main(ActivityThread.java:5017)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at java.lang.reflect.Method.invokeNative(Native Method)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at java.lang.reflect.Method.invoke(Method.java:515)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
08-14 03:00:40.384: E/AndroidRuntime(1506):     at dalvik.system.NativeStart.main(Native Method)
08-14 03:00:40.574: W/ActivityManager(383):   Force finishing activity org.diebao.rbbb/.activity.FeedListing
08-14 03:00:40.614: W/ActivityManager(383):   Force finishing activity org.diebao.rbbb/.activity.CategoryListing

注意:我已经搜索过类似的问题,但我找不到一个非常相似或非常接近的问题。因此,功能实现没有错,因为它适用于许多设备没有问题,只是某些Android设备遇到了错误。也许我需要更改编码的某些部分以使其流畅并使应用程序广泛可靠。

感谢您的帮助。

【问题讨论】:

  • 在应用标签下的清单中尝试 large heap = true...不确定是否有用
  • 您正在加载的图像可能太大,请查看此链接:developer.android.com/training/displaying-bitmaps/…
  • 我通过编写一些用于处理大型位图的行来遇到这种情况......使用 Matrix 类。
  • 我在 Manifest 中尝试了 android:largeHeap="true" 但没有成功。

标签: android out-of-memory listadapter bitmapfactory


【解决方案1】:

位图处理在 Android 中并非易事。不可能指向一行代码并告诉您只需更改它即可。有很多方面需要注意。

Android 文档很好地概述了需要考虑的事项。有几点是:

使用android:largeHeap is really discouraged 的提示,因为它是一种黑客行为,除了最极端的情况外,几乎在所有情况下都被认为是不好的做法。通常你应该对你的应用程序的内存效率进行编码,而不是仅仅使用更多的内存。

对于大多数此类问题的简单实施,我建议查看Picasso,它会为您处理加载、缩减和缓存,只需一行代码。

【讨论】:

  • 解释清楚了,谢谢。但是我还不够优秀,无法浏览您的每个链接并找到最灵活的方式来在我的代码中实现。如果你能根据我上面的问题给我一些具体的建议,我会很高兴。
  • 看看答案,跟着毕加索走。但我也敦促您阅读并理解 android 文档中的主题,因为了解事物在 android 中的工作方式至关重要。如果你不喜欢使用另一个库,你必须自己实现一个 lru 位图缓存(或使用代码 sn-ps)并负责加载位图(但你必须阅读文档)
  • 函数实现没有错,因为它适用于许多设备没有问题,只是某些Android设备遇到了错误。也许我需要更改编码的某些部分以使其流畅并使应用程序可靠,而不是使用另一种或多种方法。
  • 如果您的内存设计在单个设备上失败,则说明您的代码存在缺陷。关键是您必须考虑不同的环境(320x480 屏幕设备通常具有较少的 RAM,但也很少需要全分辨率图像)。这就是为什么我说它不是微不足道的,不能用一行代码来解决。我将首先实现 lru 缓存和\或将图像缩小到所需的分辨率(如果它们不是资源)。
猜你喜欢
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 2016-08-28
相关资源
最近更新 更多