【问题标题】:What are the main reasons for java.lang.OutOfMemoryError in androidandroid中java.lang.OutOfMemoryError的主要原因是什么
【发布时间】:2012-05-29 14:21:09
【问题描述】:

我是 android 和 java 的新手。我制作了一个运行良好的应用程序,除了当我向下滚动应用程序中的列表视图时出现 java.lang.OutOfMemoryError 异常,每次滚动到底部时都会动态增加(10 个项目)。滚动一些 4-5 页后,我得到了这个异常。谁能帮我解决这个异常以及避免此类异常的一些技巧。

我的适配器:

public class LazyAdapter extends BaseAdapter{

    private static LayoutInflater inflater = null;
    private Activity activity;
    public ImageLoader imageLoader;
    public static ArrayList<Product> values;
    private String product_action;

    public LazyAdapter(Activity a, ArrayList<Product> arg3) {

        values = arg3;
        activity = a;
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader = new ImageLoader(activity.getApplicationContext());
    }

    public int getCount() {

        return values.size();
    }

    public Object getItem(int position) {

        return position;
    }

    public long getItemId(int position) {

        return position;
    }

    public static class ViewHolder {

        public TextView text;
        public ImageView image;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        View vi = convertView;
        ViewHolder holder;

        Product p = values.get(position);

        if (convertView == null) {
            vi = inflater.inflate(R.layout.feed_items, null);
            holder = new ViewHolder();
            holder.text = (TextView) vi.findViewById(R.id.label);
            ;
            holder.image = (ImageView) vi.findViewById(R.id.logo);
            vi.setTag(holder);
        } else {
            holder = (ViewHolder) vi.getTag();
        }

        if (condition1) {
            holder.text.setText(myText);
            holder.image.setTag(imageUrl);

            imageLoader.DisplayImage(imgURL, activity, holder.image);
        } else if (condition2) {
            holder.text.setText(myText);
                    holder.image.setTag(imageUrl);
            imageLoader.DisplayImage(imgURL, activity, holder.image);
        } else if (condition3) {
            holder.text.setText(myText);
            holder.image.setTag(imageUrl);

            imageLoader.DisplayImage(imgURL), activity,
                    holder.image);
        }

        return vi;
    }

    public void add(Product product) {

        values.add(product);
    }

}

【问题讨论】:

  • 这里有一大堆代码很难阅读,可能应该重构,但是 LazyAdapter 的实现是什么?
  • 我在问题中添加了我的适配器代码,请检查

标签: java android memory-management memory-leaks out-of-memory


【解决方案1】:

java.lang.outofmemmory dvm 没有内存空间时发生错误。这就是内存泄漏的问题。当应用程序保留对对象的引用越来越多并且从不释放它们时,就会发生内存泄漏。因此,垃圾收集器将永远不会收集这些对象,并且可用内存将越来越少,直到我们达到没有足够可用内存供应用程序正常运行的程度。

当使用可用平台资源无法满足内存请求时引发。这样的请求可以由正在运行的应用程序或由 VM 的内部功能发出。每次滚动列表时还有一件事,那么 vm 需要内存来显示该列表,以便释放具有前一个视图的列表对象。

要解决这个问题,首先创建一个 XML 文件,在其中创建一个像这样的 ListView(Xmlfilename 是 yourlist.xml):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearlayout_id"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" 
    android:background="@color/encode_view">

<ListView
    android:id="@+id/info_list_id"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_above="@+id/cancelinfobtn_id" >
</ListView>
</RelativeLayout>

现在创建一个 XML,在其中创建您的 ImageViewTextView。 (XML 文件名:yourimagetextlayout.xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="5dp" 
    android:background="#ffffff">
    <ImageView
        android:id="@+id/logo"
        android:layout_width="50px"
        android:layout_height="50px"
        android:layout_marginLeft="5px"
        android:layout_marginRight="20px"
        android:layout_marginTop="5px"
        android:layout_weight="0.25"
        android:src="@drawable/your image source name" />

    <TextView
        android:id="@+id/label"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@+id/logo"
        android:text="@+id/label"
        android:textSize="16px" 
        android:textColor="@color/contents_text"/>

</RelativeLayout>

现在您有了 Activity 类,您可以在其中通过其 ID 找到您的 ListView 并创建一个自定义适配器类,您可以在其中填写您的列表,如下所示:

public class MobileArrayAdapter extends ArrayAdapter<String>
{
    private final Context context;
    private ArrayList<String> contactNamesList;
    View rowView;
    ImageView imageview;

    public MobileArrayAdapter(Context context, ArrayList<String> contactNamesList) {
        super(context, R.layout.yourimagetextlayout, contactNamesList);
        this.context = context;
        this.contactNamesList = new ArrayList<String>();
        this.contactNamesList.addAll(contactNamesList);
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rowView = inflater.inflate(R.layout.yourimagetextlayout, parent, false);
        TextView textView = (TextView) rowView.findViewById(R.id.label);
        imageview = (ImageView) rowView.findViewById(R.id.logo);
        String findname=contactNamesList.get(position);
        textView.setText(contactNamesList.get(position));
        imageview.setImageBitmap(ur image phto path);
        return rowView;
    }

}

现在在您的 Activity 类中通过其 ID 找到您的 ListView

ListView listview = (ListView)findViewById(R.id.info_list_id);

只需像这样实例化适配器类:

MobileArrayAdapter mobileadapter = new MobileArrayAdapter(this, yourarraylist);

并将这个适配器添加到您的 ListView 中:

listview.setAdapter(mobileadapter);

【讨论】:

    猜你喜欢
    • 2017-07-03
    • 1970-01-01
    • 2014-12-24
    • 2012-10-05
    • 2011-06-23
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多