After redesigning an app we got larger load times on new views create (the old version had almost no images and was much faster). We use ViewFlipper to navigate through the views. The first two views, which are created, are two layouts with ListViews, whose elements have background images and other graphics. Coincidentally we found, that each time, when a new View is created and is put on the view stack, the app calculates the dimensions of each existing view (Among other calls the getView() method of the ListView adapters several times). The trace log of each call looks like:
LinearLayout.measureChildBeforeLayout(View, int, int, int, int, int) line: 1369 LinearLayout.measureVertical(int, int) line: 660 LinearLayout.onMeasure(int, int) line: 553 LinearLayout(View).measure(int, int) line: 12937 TabHost(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5045 TabHost(FrameLayout).onMeasure(int, int) line: 293 TabHost(View).measure(int, int) line: 12937 RelativeLayout.measureChildHorizontal(View, RelativeLayout$LayoutParams, int, int) line: 594 RelativeLayout.onMeasure(int, int) line: 376 RelativeLayout(View).measure(int, int) line: 12937 FrameLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5045 FrameLayout.onMeasure(int, int) line: 293 FrameLayout(View).measure(int, int) line: 12937 LinearLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5045 LinearLayout.measureChildBeforeLayout(View, int, int, int, int, int) line: 1369 LinearLayout.measureVertical(int, int) line: 660 LinearLayout.onMeasure(int, int) line: 553 LinearLayout(View).measure(int, int) line: 12937 PhoneWindow$DecorView(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5045 PhoneWindow$DecorView(FrameLayout).onMeasure(int, int) line: 293 PhoneWindow$DecorView.onMeasure(int, int) line: 2180 PhoneWindow$DecorView(View).measure(int, int) line: 12937
and so on…
I think it is the reason why the app has become so slow.
What can I do to prevent the app to do these measures or to make the app faster?
ListAdapter getView():
public View getView(int pos, View convertView, ViewGroup parent) {
View row;
Entry entry = null;
if (objects.get(pos) instanceof Entry) {
entry = (Entry) objects.get(pos) ;
Boolean isGroupedEntry;
if (entry.getGroup() != null && entry.isGroupedEntry()) {
isGroupedEntry = true;
} else {
isGroupedEntry = false;
}
if (convertView != null) {
row = convertView;
} else {
row = new EntryBoxFrameLayout(getContext());
}
((EntryBoxFrameLayout) row).configureFor(entry);
} else {
row = new View(ContentManager.getInstance().getContext());
}
row.setSelected(false);
row.setTag(pos);
return row;
}
in configureFor() i set some texts and then:
if (entry.getUserIsSignedUp() > 0) {
this.setBackgroundColor("4A4A4A");
this.findViewById(R.id.star).setVisibility(View.VISIBLE);
this.findViewById(R.id.entry_face).setBackgroundResource(R.drawable.entry_face_loggedin);
fulldate.setTextColor(Color.BLACK);
} else {
this.setBackgroundColor(entry.getColorHex());
this.findViewById(R.id.star).setVisibility(View.INVISIBLE);
this.findViewById(R.id.entry_face).setBackgroundResource(R.drawable.entry_face);
fulldate.setTextColor(Color.WHITE);
}
if (entry.getGroup() != null) {
this.findViewById(R.id.imgGroupArrow).setVisibility(View.VISIBLE);
if (entry.isGroupExpanded()) {
((ImageView)this.findViewById(R.id.imgGroupArrow)).setImageResource(R.drawable.entry_up_arrow);
} else {
((ImageView)this.findViewById(R.id.imgGroupArrow)).setImageResource(R.drawable.entry_down_arrow);
}
this.setGroupContainer(true);
} else {
this.findViewById(R.id.imgGroupArrow).setVisibility(View.INVISIBLE);
this.setGroupContainer(false);
}
String filename = entry.getCacheFilename();
Drawable entryimage = null;
if (filename != null) {
try {
FileInputStream input = ContentManager.getInstance().getContext().openFileInput(filename);
entryimage = new BitmapDrawable(ContentManager.getInstance().getContext().getResources(), input);
input.close();
} catch (Exception e) {
Log.e(e.getLocalizedMessage());
}
}
if (entryimage != null) {
this.getImageView().setImageDrawable(entryimage);
} else {
this.getImageView().setImageResource(R.drawable.entry_placeholder);
}
The getView() method is slowing your application down. The listView recycles view objects for performance.
There are many learning resources covering this.
From google I/O conference and from creator of listView: Romain Guy
Optimisation regarding images
For more code examples: