自定义ArrayAdapter for listView,图像内存不足

时间:2016-05-31 14:22:48

标签: android image out-of-memory android-arrayadapter

我试图显示来自xml文件的数据,我编写了一个将信息解析为列表的类,我需要显示每个项目的图片和tostring,我创建了一个自定义的ArrayAdapter。由于某种原因,当我使用活动

时,这个错误会不断弹出
05-31 17:14:13.338 24755-24755/com.yuvaleliav1gmail.foodchain E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                Process: com.yuvaleliav1gmail.foodchain, PID: 24755
                                                                                java.lang.OutOfMemoryError: Failed to allocate a 63489036 byte allocation with 16777216 free bytes and 20MB until OOM
                                                                                    at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
                                                                                    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
                                                                                    at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:882)
                                                                                    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:858)
                                                                                    at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:478)
                                                                                    at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:516)
                                                                                    at android.graphics.drawable.Drawable.createFromPath(Drawable.java:2577)
                                                                                    at com.yuvaleliav1gmail.foodchain.CustomListViewAdapter.getView(CustomListViewAdapter.java:52)
                                                                                    at android.widget.AbsListView.obtainView(AbsListView.java:2929)
                                                                                    at android.widget.ListView.makeAndAddView(ListView.java:1945)
                                                                                    at android.widget.ListView.fillUp(ListView.java:755)
                                                                                    at android.widget.ListView.correctTooHigh(ListView.java:1456)
                                                                                    at android.widget.ListView.fillGap(ListView.java:684)
                                                                                    at android.widget.AbsListView.trackMotionScroll(AbsListView.java:7293)
                                                                                    at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:4391)
                                                                                    at android.widget.AbsListView.onTouchMove(AbsListView.java:5782)
                                                                                    at android.widget.AbsListView.onTouchEvent(AbsListView.java:5610)
                                                                                    at android.view.View.dispatchTouchEvent(View.java:9993)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2828)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2499)
                                                                                    at android.widget.AbsListView.dispatchTouchEvent(AbsListView.java:5547)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2839)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2514)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2839)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2514)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2839)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2514)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2839)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2514)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2839)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2514)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2839)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2514)
                                                                                    at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2831)
                                                                                    at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1863)
                                                                                    at android.app.Activity.dispatchTouchEvent(Activity.java:3046)
                                                                                    at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
                                                                                    at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2792)
                                                                                    at android.view.View.dispatchPointerEvent(View.java:10228)
                                                                                    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5344)
                                                                                    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5180)
                                                                                    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4620)
                                                                                    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4673)
                                                                                    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4639)
                                                                                    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4781)
                                                                                    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4647)
                                                                                    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4838)
                                                                                    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4620)
                                                                                    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4673)
                                                                                    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4639)
                                                                                    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4647)
                                                                                    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4620)
                                                                                    at android.view.ViewRootImpl.deliverI

这是代码:

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * Created by rippe on 5/31/2016.
 */
public class CustomListViewAdapter extends ArrayAdapter<Meal> {


    Context context;

    public CustomListViewAdapter(Context context, int resourceId, //resourceId=your layout
                                 List<Meal> items) {
        super(context, resourceId, items);
        this.context = context;
    }

    /*private view holder class*/
    private class ViewHolder {
        ImageView imageView;
        TextView txtTitle;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        Meal rowItem = getItem(position);

        LayoutInflater mInflater = (LayoutInflater) context
                .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_item, null);
            holder = new ViewHolder();
            holder.txtTitle = (TextView) convertView.findViewById(R.id.title555);
            holder.imageView = (ImageView) convertView.findViewById(R.id.icon555);
            convertView.setTag(holder);
        } else
            holder = (ViewHolder) convertView.getTag();

        holder.txtTitle.setText(rowItem.toString());
        if(rowItem.getPicPath().compareTo("") != 0)
            holder.imageView.setImageDrawable(Drawable.createFromPath(rowItem.getPicPath()));

        return convertView;
    }
}

这是活动:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

public class XmlPullParser extends AppCompatActivity {

        ListView listView;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_xml_pull_parser);

            listView = (ListView) findViewById(R.id.list);

            List<Meal> meals = null;
            try {
                XMLPullParserHandler parser = new XMLPullParserHandler();
                meals = parser.parse(getStringFromFile(Globals.xmlFilePath));
                CustomListViewAdapter adapter =
                        new CustomListViewAdapter(this,R.layout.list_item, meals);
                listView.setAdapter(adapter);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    public static FileInputStream getStringFromFile (String filePath) throws Exception {
        File fl = new File(filePath);
        FileInputStream fin = new FileInputStream(fl);
        return fin;
    }
}

这是解析器:虽然我不瘦,问题出在解析器中但是在自定义ArrayAdapter中......

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;


class XMLPullParserHandler {
    List<Meal> meals;
    private Meal meal;
    private String text;

    public XMLPullParserHandler() {
        meals = new ArrayList<Meal>();
    }

    public List<Meal> getMeals() {
        return meals;
    }

    public List<Meal> parse(InputStream is) {
        XmlPullParserFactory factory = null;
        XmlPullParser parser = null;
        try {
            factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            parser = factory.newPullParser();

            parser.setInput(is, null);

            int eventType = parser.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                String tagname = parser.getName();
                switch (eventType) {
                    case XmlPullParser.START_TAG:
                        if (tagname.equalsIgnoreCase("Meal") || tagname.equalsIgnoreCase("Comment") || tagname.equalsIgnoreCase("Weight")) {
                            meal = new Meal();
                            meal.setTimestamp(parser.getAttributeValue(0));
                        }
                        break;

                    case XmlPullParser.TEXT:
                        text = parser.getText();
                        break;

                    case XmlPullParser.END_TAG:
                        if (tagname.equalsIgnoreCase("Meal") || tagname.equalsIgnoreCase("Comment") || tagname.equalsIgnoreCase("Weight")) {
                            // add employee object to list
                            meals.add(meal);
                        } else if (tagname.equalsIgnoreCase("Score")) {
                            meal.setScore(text);
                        } else if (tagname.equalsIgnoreCase("Description")) {
                          meal.setDescription(text);
                        } else if (tagname.equalsIgnoreCase("Note")) {
                           meal.setNotes(text);
                        } else if (tagname.equalsIgnoreCase("Picture")) {
                            meal.setPicPath(text);
                        } else if (tagname.equalsIgnoreCase("WeightNumber")) {
                            meal.setWeightNumber(text);
                        } else if (tagname.equalsIgnoreCase("CommentType")) {
                            meal.setCommentType(text);
                        }
                        break;

                    default:
                        break;
                }
                eventType = parser.next();
            }

        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return meals;
    }
}

1 个答案:

答案 0 :(得分:2)

将您加载的图片大到足以导致OutOfMemoryError,了解Loading Large Bitmaps Efficiently,或切换到使用图片加载框架,例如PicassoGlide