tsiro
tsiro

Reputation: 2403

listview viewHolder leaks memory android

Testing this class for memory issues using MAT i figured out that there 16 objects of the inner class ViewHolder according to the tool, but i do not really understand where the problem occurs. Can anyone help me, please?

public class InEnglishPlacesDataListCursorAdapter extends SimpleCursorAdapter implements OnClickListener{

    private ListPlacesFragment activity;
    private SearchPlaceResultListFragment searchPlaceResultListFragment;
    private BitmapTask imgFetcher;
    private Context context;
    private int layout;
    private Cursor cursor;
    private double current_latitude;
    private double current_longtitude;
    private String button_pressed;
    private Boolean imagessavedFlag;
    private Bitmap bitmap;
    private String fontcolor="";
    private Bitmap bit;

    GPSTracker gps;
    ArrayList<PlacesData> placesDataArray = new ArrayList<PlacesData>();


    public InEnglishPlacesDataListCursorAdapter(String button_pressed, SearchPlaceResultListFragment searchPlaceResultListFragment, Context context, int layout, Cursor cursor, String[] from, int[] to, double current_latitude, double current_longtitude, boolean imagessavedFlag, String fontcolor) {
        super(context, layout, cursor, from, to);
        this.button_pressed = button_pressed;
        this.searchPlaceResultListFragment = searchPlaceResultListFragment;
        this.context = context.getApplicationContext();
        this.layout = layout;
        this.cursor = cursor;
        //this.imgFetcher = i;
        this.current_latitude = current_latitude;
        this.current_longtitude = current_longtitude;
        this.imagessavedFlag = imagessavedFlag;
        this.fontcolor = fontcolor;
        // TODO Auto-generated constructor stub
    }

    public InEnglishPlacesDataListCursorAdapter(String button_pressed, ListPlacesFragment activity, Context context, int layout, Cursor cursor, String[] from, int[] to, double current_latitude, double current_longtitude, boolean imagessavedFlag) {
        super(context, layout, cursor, from, to);
        this.button_pressed = button_pressed;
        this.activity = activity;
        this.context = context;
        this.layout = layout;
        this.cursor = cursor;
        //this.imgFetcher = i;
        this.current_latitude = current_latitude;
        this.current_longtitude = current_longtitude;
        this.imagessavedFlag = imagessavedFlag;
        // TODO Auto-generated constructor stub
    }

    private class ViewHolder{
        TextView nametv, placeNametv, distance, latitudetv, longtitudetv, desc_infohiddentv,    menuhiddentv,
        telhiddentv, linkhiddentv, fbLinkhiddentv, emailhiddentv, exhibitionhiddentv,
        photoLink1hiddentv, photoLink2hiddentv, photoLink3hiddentv, photoLink4hiddentv;
        ImageView icon;
        Button infoButton;

        ViewHolder(View v){
            desc_infohiddentv = (TextView) v.findViewById(R.id.descinfohiddentv);
            menuhiddentv = (TextView) v.findViewById(R.id.menuhiddentv);
            telhiddentv = (TextView) v.findViewById(R.id.telhiddentv);
            linkhiddentv = (TextView) v.findViewById(R.id.linkhiddentv);
            fbLinkhiddentv = (TextView) v.findViewById(R.id.fbLinkhiddentv);
            emailhiddentv = (TextView) v.findViewById(R.id.emailhiddentv);
            exhibitionhiddentv = (TextView) v.findViewById(R.id.exhibitionhiddentv);
            photoLink1hiddentv = (TextView) v.findViewById(R.id.photoLink1hiddentv);
            photoLink2hiddentv = (TextView) v.findViewById(R.id.photoLink2hiddentv);
            photoLink3hiddentv = (TextView) v.findViewById(R.id.photoLink3hiddentv);
            photoLink4hiddentv = (TextView) v.findViewById(R.id.photoLink4hiddentv);
            nametv = (TextView) v.findViewById(R.id.locationName);
            placeNametv = (TextView) v.findViewById(R.id.placeNametv);
            latitudetv = (TextView) v.findViewById(R.id.latitudetv);
            longtitudetv = (TextView) v.findViewById(R.id.longtitudetv);
            distance = (TextView) v.findViewById(R.id.distance);
            icon = (ImageView) v.findViewById(R.id.locationImage);
            infoButton = (Button) v.findViewById(R.id.info_button);
        }
    }



    public View getView(int pos, View inView, ViewGroup parent){
        ConnectivityManager cm = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        //imgFetcher = new BitmapTask(context.getApplicationContext());
        View v = inView;
        ViewHolder viewHolder = null;
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.places_basic_layout, parent, false);
            viewHolder = new ViewHolder(v);
            viewHolder.infoButton.setTag(viewHolder);
            v.setTag(viewHolder);   
        }
        else{
            viewHolder = (ViewHolder) v.getTag();
        }
        this.cursor.moveToPosition(pos);
        String name = this.cursor.getString(this.cursor.getColumnIndex("_id"));
        int integer_id = Integer.parseInt(name);
        String placeNameEl = this.cursor.getString(this.cursor.getColumnIndex("name_en"));
        String image_link = this.cursor.getString(this.cursor.getColumnIndex("photo_link"));
        double place_latitude = this.cursor.getDouble(this.cursor.getColumnIndex("latitude"));
        String str_placelatitude = Double.toString(place_latitude);
        double place_longtitude = this.cursor.getDouble(this.cursor.getColumnIndex("longtitude"));
        String str_placelongtitude = Double.toString(place_longtitude);
        String descInfo = this.cursor.getString(this.cursor.getColumnIndex("info_en"));
        String tel = this.cursor.getString(this.cursor.getColumnIndex("tel"));
        String link = this.cursor.getString(this.cursor.getColumnIndex("link"));
        String fbLink = this.cursor.getString(this.cursor.getColumnIndex("fb_link"));
        String email = this.cursor.getString(this.cursor.getColumnIndex("email"));
        String exhibition = this.cursor.getString(this.cursor.getColumnIndex("exhibition_en"));
        String menu = this.cursor.getString(this.cursor.getColumnIndex("menu_en"));
        String link1 = this.cursor.getString(this.cursor.getColumnIndex("link1"));
        String link2 = this.cursor.getString(this.cursor.getColumnIndex("link2"));
        String link3 = this.cursor.getString(this.cursor.getColumnIndex("link3"));
        String link4 = this.cursor.getString(this.cursor.getColumnIndex("link4"));


        double apostasi = GPSTracker.getDistance(this.current_latitude, this.current_longtitude, place_latitude, place_longtitude);
        double distanceInKm = apostasi/1000;
        DecimalFormat df = new DecimalFormat("#.##");
        String dx=df.format(distanceInKm);


        viewHolder.nametv.setText(name);
        viewHolder.desc_infohiddentv.setText(descInfo);
        viewHolder.menuhiddentv.setText(menu);
        viewHolder.telhiddentv.setText(tel);
        viewHolder.linkhiddentv.setText(link);
        viewHolder.fbLinkhiddentv.setText(fbLink);
        viewHolder.emailhiddentv.setText(email);
        viewHolder.exhibitionhiddentv.setText(exhibition);
        viewHolder.photoLink1hiddentv.setText(link1);
        viewHolder.photoLink2hiddentv.setText(link2);
        viewHolder.photoLink3hiddentv.setText(link3);
        viewHolder.photoLink4hiddentv.setText(link4);
        viewHolder.placeNametv.setText(placeNameEl);
        if (fontcolor.equals("black")){ 
            viewHolder.placeNametv.setText(placeNameEl);
            viewHolder.distance.setText(dx + " km");
            viewHolder.distance.setTextColor(Color.BLACK);
            viewHolder.distance.setTypeface(null, Typeface.BOLD);
            viewHolder.placeNametv.setTextColor(Color.BLACK);
            viewHolder.placeNametv.setTypeface(null, Typeface.BOLD);
        }
        else{
            viewHolder.placeNametv.setText(placeNameEl);
            viewHolder.distance.setText(dx + " km");
        }
        //viewHolder.surnametv.setTag(surname);
        viewHolder.latitudetv.setText(str_placelatitude);
        viewHolder.longtitudetv.setText(str_placelongtitude);
        viewHolder.infoButton.setOnClickListener(this);

        return v;
    }
    ![][1]
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        //TextView surnametv = (TextView) v.findViewById(R.id.nameEl);
        //Button pressed = (Button) v;
        //String button_pressed_text = pressed.getText().toString();
        Log.i("Button pressed text =>", " " + button_pressed);

        ViewHolder vH = (ViewHolder) v.getTag();
        //String url = (String) vH.surnametv.getTag();
        //Toast.makeText(this.context, url, Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(context.getApplicationContext(), PlacesDetailsTabs.class);
        //Intent intent = new Intent(this.activity, PlacesListFragmentActivityTest.class);
        //intent.putExtra("nameEl", vH.surnametv.getTag().toString());
        String str_current_latitude = Double.toString(current_latitude);
        String str_current_longtitude = Double.toString(current_longtitude);
        intent.putExtra("language", "English");
        intent.putExtra("current latitude" , str_current_latitude);
        intent.putExtra("current longtitude", str_current_longtitude);
        intent.putExtra("placeNameEl", vH.placeNametv.getText());
        intent.putExtra("desc_info", vH.desc_infohiddentv.getText());
        intent.putExtra("menu", vH.menuhiddentv.getText());
        intent.putExtra("telephone", vH.telhiddentv.getText());
        intent.putExtra("link", vH.linkhiddentv.getText());
        intent.putExtra("fbLink", vH.fbLinkhiddentv.getText());
        intent.putExtra("email", vH.emailhiddentv.getText());
        intent.putExtra("exhibition", vH.exhibitionhiddentv.getText());
        intent.putExtra("photoLink1", vH.photoLink1hiddentv.getText());
        intent.putExtra("photoLink2", vH.photoLink2hiddentv.getText());
        intent.putExtra("photoLink3", vH.photoLink3hiddentv.getText());
        intent.putExtra("photoLink4", vH.photoLink4hiddentv.getText());
        intent.putExtra("latitude", vH.latitudetv.getText());
        intent.putExtra("longtitude", vH.longtitudetv.getText());
        intent.putExtra("button_pressed_text", button_pressed);
        intent.putExtra("displaycurrentPoint", "yes");
        //Toast.makeText(this.context, vH.photoLink1hiddentv.getText(), Toast.LENGTH_SHORT).show();
        //intent.putExtra("latitude", this.c.getDouble(this.c.getColumnIndex("latitude")));
        //intent.putExtra("longtitude", this.c.getDouble(this.c.getColumnIndex("longtitude")));
        if (this.activity == null){
            this.searchPlaceResultListFragment.startActivity(intent);
        }else{
            this.activity.startActivity(intent);
        }
    }



}

Upvotes: 1

Views: 1015

Answers (2)

Danial Hussain
Danial Hussain

Reputation: 2530

There is plenty of things you should see.

1st you must knew that getView function is called everytime you scroll your list or with each item you insert. So, the cracks of my point is that your getView function should be neat and clean. Means it just shows value not to populate it inside the getView.

Precautions :

1) Check connectivity outside the adapter.

2) Create a static viewHolder class so that it will be created once.

3) you must populate a ArrayList of objects outside getView and then use that List inside getView.

Upvotes: 0

Suhail Mehta
Suhail Mehta

Reputation: 5542

make the ViewHolder class as static inner class.

Just add

static class ViewHolder{}

This is avoid multiple object formation of viewHolder.

Follow this tutorial ,will help you understand list view better https://www.youtube.com/watch?v=wDBM6wVEO70

Upvotes: 1

Related Questions