使用应用程序超过 5-10 分钟后出现内存不足错误

Out of Memory error after using app for more than 5-10 mins

当我使用我的应用程序超过 7-8 分钟时,由于布局充气器,我一直在关注内存不足问题。我已经检查了 Whosebug 中的许多问题,但未能找到好的解决方案。我也试过 'android:largeHeap="true"',但它似乎产生了比解决这个问题更多的问题。

包含列表视图的片段如下:我在其中加载了大量项目详细信息,这通常会导致内存不足错误:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    viewX = inflater.inflate(R.layout.item_list, container, false);
    baseURL = getResources().getString(R.string.baseURL);
    ((MainActivity) getActivity()).setBack(0);
    ((MainActivity) getActivity()).setBack_match(2);
    ((MainActivity) getActivity()).setBackIcon(0);  
    search = (SearchView) viewX.findViewById(R.id.search);
    listView = (SwipeMenuListView) viewX.findViewById(R.id.listView);
    layout = (LinearLayout) viewX.findViewById(R.id.layout2);
    progress = (ProgressBar) viewX.findViewById(R.id.progress2);
    list_notice = (TextView) viewX.findViewById(R.id.list_notice);
    list_title = (TextView) viewX.findViewById(R.id.list_title);

    me_latLng = ((MainActivity) getActivity()).getUserLatLng();
    likeFav = ((MainActivity) getActivity()).likeFavX();
    device_id = ((MainActivity) getActivity()).getDeviceId();
    token = ((MainActivity) getActivity()).getToken();
    BG = ((MainActivity) getActivity()).getCarBG();

    if (me_latLng == null) {
        me_latLng = new LatLng(0, 0);
        distance_check = 1;
    }        
    if (likeFav == 1) {
        list_title.setText("LIKED CARS");
        likeFav = 1;
        list("like");
    }
    if (likeFav == 0) {
        list_title.setText("FAVOURITE CARS");
        likeFav = 0;
        list("fav");
    }

    SwipeMenuCreator creator = new SwipeMenuCreator() {
        @Override
        public void create(SwipeMenu menu) {


            // create "delete" item
            SwipeMenuItem deleteItem = new SwipeMenuItem(
                    getActivity());
            // set item background
            deleteItem.setBackground(new ColorDrawable(Color.rgb(0x7a,
                    0x01, 0x3a)));
            // set item width
            deleteItem.setWidth(150);
            // set a icon
            deleteItem.setIcon(R.drawable.delete);
            // add to menu
            menu.addMenuItem(deleteItem);
        }
    };

listView.setMenuCreator(creator);
    listView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
            int[] vNew = ((MainActivity) getActivity()).getPos();

            final int positionNew = vNew[position];
            switch (index) {
                case 0:
                    final int position2 = position;
                    new AlertDialog.Builder(getActivity())
                            .setTitle("")
                            .setMessage("Are you sure you want to delete car: " + brand_list[positionNew] + ", " + model_list[positionNew])
                            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    if (likeFav == 1) {
                                        deleteLikeFav(baseURL + "RemoveLike", "" + assetId_list[positionNew]);
                                    } else {
                                        deleteLikeFav(baseURL + "RemoveFavourite", "" + assetId_list[positionNew]);
                                    }
                                    dialog.dismiss();
                                }
                            })
                            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            })
                            .show();
                    break;
            }
           return false;
        }
    });

    listView.setSwipeDirection(SwipeMenuListView.DIRECTION_LEFT);
    search.setOnQueryTextListener(item_list.this);
    return viewX;
}

private void deleteLikeFav(final String s, final String assetIdXXX) {
    RequestQueue rq = Volley.newRequestQueue(getActivity());
    StringRequest postReq = new StringRequest(Request.Method.POST, s, new Response.Listener<String>() {

        @Override
        public void onResponse(String response) {
            try {
                JSONObject jsonResponse = new JSONObject(response);

                String ResponseType = jsonResponse.getString("ResponseType"),
                        network = jsonResponse.getString("ResponseMessage");

                if (network.equals("success")) {
                    if (likeFav == 1) {
                        likeFav = 1;
                        list("like");
                    } else if (likeFav == 0) {
                        likeFav = 0;
                        list("fav");
                    }
                } else if (network.equals("Token Unavailabele or Expired!")) {
                    ((MainActivity) getActivity()).renewToken();
                    token = ((MainActivity) getActivity()).getToken();
                    deleteLikeFav(s, assetIdXXX);
                } 
            } catch (Exception e) {
                e.printStackTrace();
                 }


        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            System.out.println("Error [" + error + "]");

        }
    }) {


        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("deviceid", device_id);
            params.put("token", token);
            params.put("web-method", "api");
            params.put("AssetID", assetIdXXX);
            return params;
        }


    };
    rq.add(postReq);
}

public void list(String favLike) {
    if (favLike.equals("fav")) {
        getLikeFav(baseURL + "GetFavouriteCar");
    } else {
        getLikeFav(baseURL + "GetLikedCar");
    }
}

AdapterView.OnItemClickListener listener = new AdapterView.OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        int[] v = ((MainActivity) getActivity()).getPos();
        int x = v[position];
        ((MainActivity) getActivity()).setNum_list(x);
        ((MainActivity) getActivity()).setList_flag("on");
        ((MainActivity) getActivity()).setBack(1);

        Fragment fragment = new item_details();
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.linear_view, fragment).addToBackStack(null).commit();
    }
};


public void getLikeFav(final String url) {
    num_list = 0;
    layout.setVisibility(View.VISIBLE);
    RequestQueue rq = Volley.newRequestQueue(getActivity());
    StringRequest postReq = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {

        @Override
        public void onResponse(String response) {


            try {
                String text = "Liked Car";
                if (likeFav == 1) {
                    text = "Liked Car";
                } else {
                    text = "Favourite Car";
                }
                String network = new JSONObject(response).getString("ResponseMessage");
                if (network.equals("Token Unavailabele or Expired!")) {
                    ((MainActivity) getActivity()).renewToken();
                    token = ((MainActivity) getActivity()).getToken();
                    getLikeFav(url);
                }

                JSONArray array = new JSONObject(response).getJSONArray(text);

                arrayLength_list = array.length();
                assetId_list = new int[array.length()];
                brand_list = new String[array.length()];
                model_list = new String[array.length()];
                version_list = new String[array.length()];
                price_list = new int[array.length()];
                fuel_list = new String[array.length()];
                color_list = new String[array.length()];
                fav_list = new String[array.length()];
                trans_list = new String[array.length()];
                doors_list = new String[array.length()];
                newOld_list = new String[array.length()];
                image_list = new String[array.length()];
                d_num_list = new String[array.length()];
                d_name_list = new String[array.length()];
                d_street_list = new String[array.length()];
                d_zip_list = new String[array.length()];
                d_location_list = new String[array.length()];
                d_phone_list = new String[array.length()];
                d_email_list = new String[array.length()];
                d_image_list = new String[array.length()];
                d_lat_list = new String[array.length()];
                d_long_list = new String[array.length()];
                d_whatsApp_list = new String[array.length()];
                distance_list = new String[array.length()];
                ((MainActivity) getActivity()).setposPos(array.length());
                ((MainActivity) getActivity()).setDistance_array(array.length());


                for (int i = 0; i < array.length(); i++) {
                    JSONObject j_object = array.getJSONObject(i);
                    assetId_list[i] = j_object.getInt("AssetID");
                    brand_list[i] = j_object.getString("Brand");
                    model_list[i] = j_object.getString("Model");
                    version_list[i] = j_object.getString("Version");
                    price_list[i] = j_object.getInt("Price");
                    fuel_list[i] = j_object.getString("Fuel");
                    color_list[i] = j_object.getString("Color");
                    trans_list[i] = j_object.getString("Transmission");
                    doors_list[i] = j_object.getString("NumDoors");
                    newOld_list[i] = j_object.getString("NewVehicle");
                    image_list[i] = j_object.getString("ImagePath");
                    if (likeFav == 1) {
                        fav_list[i] = j_object.getString("Favourite");
                    } else {
                        fav_list[i] = "true";
                    }
                    d_num_list[i] = j_object.getString("RDCProviderNumber");
                    d_name_list[i] = j_object.getString("ProviderName");
                    d_street_list[i] = j_object.getString("ProviderStreetName");
                    d_zip_list[i] = j_object.getString("ProviderZipCode");
                    d_location_list[i] = j_object.getString("ProviderLocation");
                    d_phone_list[i] = j_object.getString("ProviderPhone");
                    d_whatsApp_list[i] = j_object.getString("WhatsAppNumber");
                    d_email_list[i] = j_object.getString("ProviderEmail");
                    d_image_list[i] = j_object.getString("ProviderImage");

                    d_lat_list[i] = j_object.getString("Latitude");
                    d_long_list[i] = j_object.getString("Longitude");

                }

                data = new ArrayList<Data>();
                for (int i = 0; i < brand_list.length; i++) {
                    String priceStandard = "";
                    String price2X = "" + price_list[i];
                    if (price2X.length() > 6) {
                        String priceX1 = new StringBuffer(price2X).insert(price2X.length() - 6, ".").toString();
                        priceStandard = new StringBuffer(priceX1).insert(priceX1.length() - 3, ".").toString();
                    } else {
                        priceStandard = new StringBuffer(price2X).insert(price2X.length() - 3, ".").toString();
                    }
                    if (d_lat_list[i].equals("")) {
                        d_lat_list[i] = "0.0";
                    }
                    if (d_long_list[i].equals("")) {
                        d_long_list[i] = "0.0";
                    }

                    distance_list[i] = getDistance(me_latLng, new LatLng(Double.parseDouble(d_lat_list[i]), Double.parseDouble(d_long_list[i])));
                    Data searchList = new Data(model_list[i], brand_list[i], version_list[i], image_list[i], priceStandard + ",-", newOld_list[i], fav_list[i], distance_list[i], i);

                    data.add(searchList);
                    ((MainActivity) getActivity()).setPos(i, i);
                }

                myAdapter = new MyAdapter(getActivity(), data);

                listView.setAdapter(myAdapter);
                listView.setTextFilterEnabled(true);
                listView.setOnItemClickListener(listener);
                ((MainActivity) getActivity()).setList(assetId_list, image_list, brand_list, model_list, version_list, price_list, newOld_list, color_list, fuel_list, doors_list, fav_list, trans_list,
                        d_name_list, d_location_list, d_street_list, d_phone_list, d_image_list, d_lat_list, d_long_list, d_whatsApp_list, d_num_list, d_email_list);

                if (array.length() == 0) {
                    layout.setVisibility(View.VISIBLE);
                    progress.setVisibility(View.GONE);
                    list_notice.setVisibility(View.VISIBLE);
                    if (likeFav == 1) {
                        list_notice.setText("No liked cars to display");
                    } else {
                        list_notice.setText("No favourite cars to display");
                    }

                } else {
                    layout.setVisibility(View.GONE);
                    progress.setVisibility(View.VISIBLE);
                    list_notice.setVisibility(View.GONE);
                }


            } catch (Exception e) {

            }


        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            System.out.println("Error [" + error + "]");
           }
    }) {


        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("deviceid", device_id);

            params.put("token", token);
            params.put("web-method", "api");
            return params;
        }


    };
    rq.add(postReq);


}


public String getDistance(LatLng my_latlong, LatLng frnd_latlong) {
    String dist;
    if (distance_check == 0) {
        Location l1 = new Location("One");
        l1.setLatitude(my_latlong.latitude);
        l1.setLongitude(my_latlong.longitude);

        Location l2 = new Location("Two");
        l2.setLatitude(frnd_latlong.latitude);
        l2.setLongitude(frnd_latlong.longitude);

        float distance = l1.distanceTo(l2);
        int dd = (int) (distance / 1000);
        dist = dd + "";
        if (dist.equals("0")) {
            dist = "<1";
        }
    } else {
        dist = " ";
    }


    return dist;
}

@Override
public boolean onQueryTextSubmit(String query) {
    if (searchCheck == 1) {
        myAdapter.getFilter().filter(query);
    }
    return false;
}

@Override
public boolean onQueryTextChange(String newText) {
    if (searchCheck == 1) {
        myAdapter.getFilter().filter(newText);
    }
    return false;
}


public class MyAdapter extends BaseAdapter implements Filterable {

    ArrayList<Data> dataList = null;
    ArrayList<Data> mStringFilterList;
    ValueFilter valueFilter;
    View row = null;
    private Context context;


    public MyAdapter(Context context, ArrayList<Data> data) {

        this.context = context;
        this.dataList = data;
        this.mStringFilterList = new ArrayList<Data>();
        this.mStringFilterList = data;
    }

    public class ViewHolderV {
        ImageView carImageV;
        TextView brandV;
        TextView modelV;
        TextView priceV;
        TextView newOldV;
        ImageView bgV;
        ImageView favV;
        TextView distanceV;
        TextView positionV;
    }

    @Override
    public int getCount() {

        return dataList.size();
    }

    @Override
    public Object getItem(int position) {
        return dataList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolderV viewHolder = new ViewHolderV();

        dataV = dataList.get(position);
        if (convertView == null) {

            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.list_view, parent, false);


            ((MainActivity) getActivity()).setNum_list(position);

            viewHolder.brandV = (TextView) row.findViewById(R.id.list_brand);
            viewHolder.modelV = (TextView) row.findViewById(R.id.list_here);
            viewHolder.priceV = (TextView) row.findViewById(R.id.list_price);
            viewHolder.newOldV = (TextView) row.findViewById(R.id.list_oldNew);
            viewHolder.distanceV = (TextView) row.findViewById(R.id.list_distance);
            viewHolder.carImageV = (ImageView) row.findViewById(R.id.list_car);
            viewHolder.bgV = (ImageView) row.findViewById(R.id.list_bg);
            viewHolder.favV = (ImageView) row.findViewById(R.id.list_fav);
            viewHolder.positionV = (TextView) row.findViewById(R.id.list_position);

            row.setTag(viewHolder);


        } else {
            viewHolder = (ViewHolderV) convertView.getTag();
        }


        ((MainActivity) getActivity()).setDistance_list(dataV.getDistance_data());
        ((MainActivity) getActivity()).setPos(position, dataV.getPosition_data());
        viewHolder.brandV.setText(dataV.getBrand_data() + " " + dataV.getModel_data());
        viewHolder.modelV.setText(dataV.getVersion_data());
        viewHolder.priceV.setText("" + dataV.getPrice_data());
        viewHolder.newOldV.setText(dataV.getNewOld_data());
        viewHolder.positionV.setText("" + dataV.getPosition_data());
        Picasso.with(getActivity()).load(dataV.getImage_data()).into(viewHolder.carImageV);
        Picasso.with(getActivity()).load(BG).into(viewHolder.bgV);
        viewHolder.distanceV.setText(dataV.getDistance_data() + " KM");
        if (dataV.getFav_data().equals("true")) {
            viewHolder.favV.setImageResource(R.drawable.fav);
        } else {
            viewHolder.favV.setImageResource(R.drawable.fav2);
        }

        searchCheck = 1;
        return row;
    }

    @Override
    public Filter getFilter() {
        if (valueFilter == null) {
            valueFilter = new ValueFilter();
        }
        return valueFilter;
    }

    private class ValueFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            ((MainActivity) getActivity()).setPosNil();

            if (constraint.length() == 0) {
                results.count = mStringFilterList.size();
                results.values = mStringFilterList;
                // mStringFilterList.addAll(dataList);
                ((MainActivity) getActivity()).setposPos(mStringFilterList.size());
            } else {

                ArrayList<Data> filterList = new ArrayList<Data>();

                for (int i = 0; i < mStringFilterList.size(); i++) {
                    if ((mStringFilterList.get(i).getBrand_data().toUpperCase() + " " + mStringFilterList.get(i).getModel_data().toUpperCase())
                            .contains(constraint.toString().toUpperCase()) || (mStringFilterList.get(i).getVersion_data().toUpperCase())
                            .contains(constraint.toString().toUpperCase())) {

                        Data d = new Data(mStringFilterList.get(i)
                                .getModel_data(), mStringFilterList.get(i)
                                .getBrand_data(), mStringFilterList.get(i)
                                .getVersion_data(), mStringFilterList.get(i)
                                .getImage_data(), mStringFilterList.get(i)
                                .getPrice_data(), mStringFilterList.get(i)
                                .getNewOld_data(), mStringFilterList.get(i)
                                .getFav_data(), mStringFilterList.get(i)
                                .getDistance_data(), mStringFilterList.get(i)
                                .getPosition_data());

                        filterList.add(d);
                    }
                }
                results.count = filterList.size();
                results.values = filterList;
                ((MainActivity) getActivity()).setposPos(filterList.size());
            }
            return results;

        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                                      FilterResults results) {
            dataList = (ArrayList<Data>) results.values;
            notifyDataSetChanged();
        }

    }
}

问题出在您的 view holder 上。 ViewHolder 模式用于优化列表占用的内存。它只会为可见部分创建 View 对象,但在你的情况下,每次你创建一个 ViewHolder,所以每当你滚动时,对象的数量就会增加,它会导致 OutOfMemoryException,唯一的纠正方法是,你需要你的代码有一些变化。请参考 this url。另见示例

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

    ViewHolderItem viewHolder;


      // The convertView argument is essentially a "ScrapView" as described is Lucas post 
      // http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
      // It will have a non-null value when ListView is asking you recycle the row layout. 
      // So, when convertView is not null, you should simply update its contents instead of inflating a new row    layout.

    if(convertView==null){

        // inflate the layout
        LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
        convertView = inflater.inflate(layoutResourceId, parent, false);

        // well set up the ViewHolder
        viewHolder = new ViewHolderItem();
        viewHolder.textViewItem = (TextView) convertView.findViewById(R.id.textViewItem);

        // store the holder with the view.
        convertView.setTag(viewHolder);

    }else{
        // we've just avoided calling findViewById() on resource everytime
        // just use the viewHolder
        viewHolder = (ViewHolderItem) convertView.getTag();
    }
....................
.............
}