Android list activity taking too long to show content

780 views Asked by At

The issue I face is that of a listactivity taking too long time to load.

I also know the reason behind this delay but unfortunately unable to fix this glitch.

Basically i have a listview which will display the list of kids which basically is a

person object displaying the following attributes (Name,Age,Sex).

Name : John Connor
Age  : 10 years, 2 months, 11days
Sex  : Male

In order to bind the kid details to a listview i use a binder class which derives from

BaseAdapter. Say KidDataBinder. Inside the getView method of the binder class I

perform the text binding to a TextView (basically this content is a part list_row_item.xml

layout)

The problem starts when i want to display the list of kids with their details including

their age (latest as per current date).

i.e. If i load the kids listactivity today, the entry shall read

Name : John Connor
Age  : 10 years, 2 months, 11days
Sex  : Male
---------------------------------
Name : Sandra Mueller
Age  : 11 years, 1 months, 2days
Sex  : Female
 .... so on 

If i read the same listactivity a day later, it should refresh the age as

Name : John Connor
Age  : 10 years, 2 months, 12days
Sex  : Male
---------------------------------
Name : Sandra Mueller
Age  : 11 years, 1 months, 3days
Sex  : Female
 .... so on 

NOTE: Note the change in the days in the Age

To achieve this, I have a utility method which basically gets the Date of Birth of the Kid

and calculates his latest age.

/* * Returns age in * years months and days format * */ private String calculateAge(String strdob) { int age; String difference; try{

    SimpleDateFormat custDateFormat = new SimpleDateFormat("MM/dd/yyyy");
    Date dob = custDateFormat.parse(strdob);
    Calendar today = Calendar.getInstance();
    Calendar cd = Calendar.getInstance();
    cd.setTime(dob);

    int dateParts[] = {Calendar.MONTH,Calendar.DAY_OF_MONTH,Calendar.YEAR};
    int diff[] = new int[3];
    for(int i = 2; i >= 0; i--)
    {
        while(!custDateFormat.format(cd.getTime()).split("/")[i].equals(custDateFormat.format(today.getTime()).split("/")[i]))
        {
            cd.add(dateParts[i],1);
            diff[i]++;
        }
    }

    difference = ""+(diff[2]+" yrs : "+diff[0])+" months : "+diff[1]+" days";

}
catch(ParseException pex){
    return "--";
}
catch(IllegalArgumentException iex){
    return "--";
}
return difference;

}

So this method helps me in fetching the latest age of the kid but the performance hit is

quite immense. Initially if the time taken to load the list of kids was 10ms. After

including the logic of calculating latest age, the delay is well almost 3500ms!!!

What's happening here is that each time the getView gets the current Kid object It has to access the date of birth(dob) field ---> call the calculateAge passing the dob ---> get the latest age --> finally set the textview item belonging to AGE

Is there a way to perform this calculation part inside the BaseAdapter class on a separate

thread or something so that this delay is minimized.

Thanks for your inputs/responses

VATSAG

3

There are 3 answers

0
zohreh On

you can use for it lazyloading.you can calculate their age outside of getview and send to your adapter other object that be consist of name,year,month,day and sex.

2
Himanshu Soni On

You need to check out on the logic for the date calculation. You can check this. It requires you to include some utility classes. Or you replace your calculation logic with the following code

GregorianCalendar d1 = new GregorianCalendar(1992, 8 - 1, 17);
GregorianCalendar d2 = new GregorianCalendar(2013, 6 - 1, 18);
d2.add(Calendar.YEAR, -d1.get(Calendar.YEAR));
d2.add(Calendar.MONTH, -d1.get(Calendar.MONTH));
d2.add(Calendar.DAY_OF_MONTH, -d1.get(Calendar.DAY_OF_MONTH) + 1);
int y = d2.get(Calendar.YEAR);
int m = d2.get(Calendar.MONTH);
int d = d2.get(Calendar.DAY_OF_MONTH) - 1;
2
vipul mittal On

You can also take logic of calculating age out of getview and calculate it before setting adapter so that each time when getView is called it wont take such a long time.

You can also write your adapter as follow. EDIT Adapter

public class MyAdapter extends Adapter{

ArrayList<Person> kids;
ArrayList<String> ages
public myAdapter(Context context,ArrayList<Person> kids,ArrayList<String> ages){
this.kids=kids;
this.ages=ages;
}

public View getView(......){
...

Person kid=kids.get(position);
String age=ages.get(position);


..
}
}

Calling it:

ArrayList<Person> kids=new ArrayList<Person>();
kids.add(..)
kids.add(..)
kids.add(..)

String[] ages=new String[kids.size()];
int i=0;
for(Person kid:kids){
   ages[i++]=calculateAge(kid.getDOB());
}

MyAdapter adapter=new MyAdapter(this,kids,ages);