当我使用我的应用程序的时间超过7-8分钟时,由于布局不足,我一直在关注内存不足问题。我已经检查了stackoverflow中的许多问题,但一直未能找到一个好的解决方案。我也试过'android:largeHeap =“true”',但它似乎比解决这个问题产生了更多的问题。
包含listview的Fragment,其中我加载了大量项目详细信息,这通常会导致outOfMemory错误,如下所示:
@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();
}
}
}
答案 0 :(得分:0)
问题在于您的观看者。 ViewHolder模式用于优化列表占用的内存。它只会为可见部分创建View对象,但是在每次创建ViewHolder的情况下,每当你滚动对象的数量会增加而且会导致OutOfMemoryException,唯一的解决方法是,你需要有你的代码有些变化。请参考this网址。也见例子
@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();
}
....................
.............
}