How can I measure the FPS of my ListView
?
See the slides 13-17 from http://code.google.com/events/io/2010/sessions/world-of-listview-android.html.
How can I measure the FPS of my ListView
?
See the slides 13-17 from http://code.google.com/events/io/2010/sessions/world-of-listview-android.html.
I don't know about calculating FPS (I guess that should be done system-wide and is not calculated per view), but you can use Hierarchy Viewer to profile performance of each View
. It gives you time needed to measure, calculate layout of, and draw each View
in milliseconds, and helps you to find slow View
objects by showing yellow and red circles indicating bad performance.
You might be interested in this ListAdapter, which will wrap another ListAdapter and print out log statements about how many views were displayed per second.
import android.database.DataSetObserver;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
public class VpsAdapter implements ListAdapter {
protected int vpsViewCount = 0;
protected long vpsStartTimeNanos = System.nanoTime();
protected ListAdapter delegate;
public VpsAdapter(ListAdapter delegate) {
super();
this.delegate = delegate;
}
public void resetViewsPerSecond() {
vpsViewCount = 0;
vpsStartTimeNanos = System.nanoTime();
}
public double getViewsPerSecond() {
final long now = System.nanoTime();
return (vpsViewCount / (double)(now - vpsStartTimeNanos)) * 1e9;
}
public int getViewsPerSecondViewCount() {
return vpsViewCount;
}
@Override
public boolean areAllItemsEnabled() {
return delegate.areAllItemsEnabled();
}
@Override
public int getCount() {
return delegate.getCount();
}
@Override
public Object getItem(int i) {
return delegate.getItem(i);
}
@Override
public long getItemId(int i) {
return delegate.getItemId(i);
}
@Override
public int getItemViewType(int i) {
return delegate.getItemViewType(i);
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
++vpsViewCount;
Log.d("VpsAdapter", String.format("VpsAdapter: %.2f views per second (%s views)", getViewsPerSecond(), getViewsPerSecondViewCount()));
return delegate.getView(i, view, viewGroup);
}
@Override
public int getViewTypeCount() {
return delegate.getViewTypeCount();
}
@Override
public boolean hasStableIds() {
return delegate.hasStableIds();
}
@Override
public boolean isEmpty() {
return delegate.isEmpty();
}
@Override
public boolean isEnabled(int i) {
return delegate.isEnabled(i);
}
@Override
public void registerDataSetObserver(DataSetObserver dataSetObserver) {
delegate.registerDataSetObserver(dataSetObserver);
}
@Override
public void unregisterDataSetObserver(DataSetObserver dataSetObserver) {
delegate.unregisterDataSetObserver(dataSetObserver);
}
}
To use, simply wrap your existing ListAdapter in a VpsAdapter, eg.
setListAdapter( new VpsAdapter( myAdapter ) );
Then call resetViewsPerSecond()
when you're ready to start timing, and getViewsPerSecond()
when you're ready to retrieve the result. The adapter will also log to the console the current vps for every call to getView()
.
I use this adapter in conjunction with ListView.smoothScrollTo( adapter.getCount()-1 )
in order to programmatically scroll the listview to the bottom and get the average vps.