Dear developers,
I am a fan of OI filemanager, and recently I am writing a static code analysis tool to conduct performance analysis for Android apps. I found a violation of "view holder" pattern in filemanager's code. This violation could affect the ListView scrolling performance.
Currently in org/openintents/filemanager/bookmarks/BookmarkListAdapter.java, the list adapter's getView() method works like this
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = mInflater.inflate(R.layout.listItem, null);
}
((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);
return convertView;
}
When the users scroll a list view, this implementation avoids inflations for each view (by using the recycled convertView), which saves CPU cycles and RAM. However, the method still invokes findViewById() every time when it is called. Android documentation says that findViewById is an expensive call, it recursively traverses a view tree to find a view matching the give ID. Google developers actually suggested a better way to implement getView(). It works like this:
We define a ViewHolder class with the field: TextView text . Then the getView() can be implemented like this:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
//we have no recycled views to use, then build new one
convertView = mInflater.inflate(R.layout.listItem, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.getViewById(R.id.text);
convertView.setTag(holder)
} else {
//use the recycled view to improve performance
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(DATA[position]);
return convertView;
}
This avoids calling findViewById frequently and will improve performance when the list contains many items or on low end devices.
you may find more useful information in thees references:
view holder pattern: http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
http://www.youtube.com/watch?v=wDBM6wVEO70
In the last Google IO video, we find that the current implementation of getView() in filemanager is a right way, but not a fast way. The video actually provides three ways: a slow way, a right way and a fast way.
Looking forward to your reply and hope I can help improve filemanager :)