单击ListView项时出现内存不足异常

时间:2016-10-07 14:25:15

标签: android listview android-studio

我正在尝试创建一个列表视图,其中包含每个元素的背景图像以及显示在顶部的文本视图。 列表视图填充正常,但直接单击该项会引发错误。

这是我的列表视图元素xml(menu_section.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="75dp">

    <ImageView
        android:id="@+id/section_bg_image"
        android:layout_width="match_parent"
        android:layout_height="75dp"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"/>


        <TextView
            android:id="@+id/section_title"
            android:layout_width="match_parent"
            android:layout_height="75dp"
            android:layout_gravity="end"
            android:background="@color/colorBlackTranslucent"
            android:gravity="right|center_vertical"
            android:paddingLeft="20dp"
            android:paddingRight="20dp"
            android:text="Hello World"
            android:textColor="@color/colorWhite"
            android:textSize="24sp" />

</RelativeLayout>

这是我的适配器MenuAdapter.java。我正在从assets文件夹加载背景图像。每张图片大约50Kb,现在总共有大约400Kb的图像(列表中有8个项目)

import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.net.Uri;
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 com.squareup.picasso.Picasso;

import java.util.List;

import com.myapp.hotel.MyUtility;
import com.myapp.hotel.R;

public class MenuAdapter extends ArrayAdapter<MenuSection> {

    Context context;
    List<MenuSection> menuSections;
    AssetManager assetManager;
    String imageUrl;

    public MenuAdapter(Context context, int resource, List<MenuSection> objects) {
        super(context, resource, objects);
        this.context = context;
        this.menuSections = objects;
        this.assetManager = context.getAssets();
    }

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

    @Override
    public MenuSection getItem(int i) {
        return menuSections.get(i);
    }

    @Override
    public long getItemId(int i) {
        return menuSections.indexOf(getItemId(i));
    }

    /* private view holder class */
    private class ViewHolder {
        ImageView menuSectionImage;
        TextView menuSectionItemText;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder holder = null;


        LayoutInflater mInflater = (LayoutInflater) context
                .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        if (view == null) {
            view = mInflater.inflate(R.layout.menu_section, null);
            holder = new ViewHolder();
            holder.menuSectionItemText = (TextView) view.findViewById(R.id.section_title);
            holder.menuSectionImage = (ImageView) view.findViewById(R.id.section_bg_image);

            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }

        MenuSection menuSection = menuSections.get(i);

        holder.menuSectionItemText.setText(menuSection.getSectionName());

        try {
            imageUrl = menuSection.getImagePath();
            if (!MyUtility.isNullOrEmpty(imageUrl)) {
                Picasso.with(holder.menuSectionImage.getContext())
                        .load(Uri.parse(imageUrl))
                        .into(holder.menuSectionImage);
            }
        } catch (Exception ex) {
            ex.printStackTrace();

        }

        return view;
    }
}

这是Fragment RestaurantFragment.java

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import java.util.List;

import com.myapp.hotel.MyUtility;
import com.myapp.hotel.R;


/**
 * A simple {@link Fragment} subclass.
 */
public class RestaurantFragment extends Fragment {
    MenuAdapter adapter;
    List<MenuSection> menuSections;
    View view;

    public RestaurantFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        if(view == null) {
            view = inflater.inflate(R.layout.fragment_restaurant, container, false);
        }
        //adapter = new ArrayAdapter<String>(RestaurantFragment.this.getContext(), R.layout.menu_view, R.id.menu_text, MyUtility.getMenuSections().toArray(new String[MyUtility.getMenuSections().size()]));
        ListView listView = (ListView) view.findViewById(R.id.menu);
        menuSections = MyUtility.getMenuSections();

        adapter = new MenuAdapter(RestaurantFragment.this.getContext(), R.layout.menu_section, menuSections);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Toast.makeText(RestaurantFragment.this.getActivity(), "Hello World",
                        Toast.LENGTH_SHORT).show();
            }
        });
        //listView.setOnItemClickListener();
        //listView.setAdapter(adapter);

        /*
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                Intent intent = new Intent(RestaurantFragment.this.getContext(), RestaurantMenuDetailsActivity.class);
                intent.putExtra("menu_section", adapter.getItem(position).toString());
                startActivity(intent);
            }
        });
        */
        return view;
    }
}

这是我在logcat中看到的错误

10-07 19:27:14.445 14925-14925/com.myapp.hotel E/InputEventReceiver: Exception dispatching input event.
10-07 19:27:14.445 14925-14925/com.myapp.hotel E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
10-07 19:27:17.155 14925-14925/com.myapp.hotel E/art: Throwing OutOfMemoryError "Failed to allocate a 10109874 byte allocation with 8141766 free bytes and 7MB until OOM"
10-07 19:27:18.195 14925-14925/com.myapp.hotel E/art: Throwing OutOfMemoryError "Failed to allocate a 10109874 byte allocation with 8141862 free bytes and 7MB until OOM"
10-07 19:27:18.195 14925-14925/com.myapp.hotel E/MessageQueue-JNI: java.lang.StackOverflowError: stack size 8MB
10-07 19:27:19.695 14925-14925/com.myapp.hotel E/art: Throwing OutOfMemoryError "Failed to allocate a 10735842 byte allocation with 7722526 free bytes and 7MB until OOM"
10-07 19:27:20.255 14925-14925/? E/art: Throwing OutOfMemoryError "Failed to allocate a 10735842 byte allocation with 7722654 free bytes and 7MB until OOM"

我错过了什么/出错了?

更新

我的所有图片总重量约为400Kb。每张约50 Kb的8幅图像。问题是,即使我注释掉整个图像加载事物并只加载文本,单击任何列表视图项时也会抛出相同的错误。所以它绝对不是与图像有关。我认为适配器出了问题..只是无法弄清楚它可能是什么!它只是一个简单的适配器!

2 个答案:

答案 0 :(得分:1)

我认为它与图像处理无关。由于getItemId()

中的无限递归,它是堆栈溢出
@Override
public long getItemId(int i) {
    // calls itself with the same value, it can not end well !
    return menuSections.indexOf(getItemId(i));
}

答案 1 :(得分:0)

您可以在应用标记内的Android Manifest中使用largeheap="true"。但最好调整图片大小。

单张照片的高度和宽度是多少?