Performance optimization in Synyx Sudoku
Now that SynyxSudoku has been on the market a little while, I want to tell a little about what kind of measurements we took to optimize the performance of it.
First of all I have to say, that this was our first android project and I’m also just a first year trainee at the moment, so there were quite a few issues, not only about the performance that had to be solved. I learned a lot in this project and want to share a bit of what I learned with you, so I hope this will help you to improve the performance of your apps, as well.
The biggest problem was probably the large number of views that the activity had at start (somewhat about 300…), so the app needed really long to start and didn’t run that fast because of it.
To track this kind of problem, google integrated the hierarchy viewer to the toolkit of android, which gives you an overview of all the currently loaded views in the selected app.
So it was soon clear, that the highscore was the big problem, because it was built as a table with as much rows as there was data – what actually causes two different performance issues, first the big number of views and second the inefficient way of creating this views.
After a little bit of research we found the solution to this in the google I/O video “Make your Android UI Fast and Efficient”, which you really should watch, if you haven’t by now!
So we found out that there’s a ListView element that takes care of such big lists as the highscore quite easily. The trick to it is, that it only has that much views loaded, as there are visible to the user and it recycles them if the scroll out of the screen -> the views that scroll out of the screen are taken out of the list, have their data replaced, and are put in on the opposite side again.
And that’s how it’s looking in the code:
First you have to overwrite the BaseAdapter from android so that you can give it your specific views to display:
public class HighscoreListAdapter extends BaseAdapter { private List valueList; private LayoutInflater inflater; public HighscoreListAdapter(List highscoreValueList, LayoutInflater inflater) { this.inflater = inflater; this.valueList = highscoreValueList; } }
and also overwrite the getView method from it, so that you can make your recycling in there:
public View getView(int position, View convertView, ViewGroup parent) { HighscoreViewHolder highscoreViewHolder; if (convertView == null) { // the first few elements of the list are created out of the xml convertView = inflater.inflate(R.layout.highscore_list_entry, null); highscoreViewHolder = new HighscoreViewHolder(); highscoreViewHolder.name = (TextView) convertView.findViewById(R.id.highscore_list_entry_name); highscoreViewHolder.score = (TextView) convertView.findViewById(R.id.highscore_list_entry_score); highscoreViewHolder.rank = (TextView) convertView.findViewById(R.id.highscore_list_entry_rank); convertView.setTag(highscoreViewHolder); convertView.setFocusable(false); } else { // recycle of the view that went out of the view highscoreViewHolder = (HighscoreViewHolder) convertView.getTag(); } HighscoreValue value = this.valueList.get(position); // set the new values highscoreViewHolder.name.setText(value.getName()); highscoreViewHolder.score.setText(Integer.toString(value.getScore())); highscoreViewHolder.rank.setText(Integer.toString(value.getRank())); return convertView; }
now whats only left is to create the adapter, and assign it to the ListView:
highscoreListAdapter = new HighscoreListAdapter(highscoreList, getLayoutInflater()); listView.setAdapter(highscoreListAdapter);
If you make some changes in the data set you gave to the adapter, just call notifyDataSetChanged() on it to let it refresh itself.
So after this change the app started remarkably faster and also ran faster then before, the views were cut to a merely 120 in numbers.
Well, that’s it for the moment. If you want further advices regarding the performance of android apps, please watch the video I mentioned above. It helped me a lot and I’m sure it will also show you a few tricks how to make your app faster.