1

Im building a sudoku and Im facing a performance issue over here.

I have this grid an I want to fill the grid with 81 cells. These cells are custom views, because I want them to have 10 labels in them en some function blabla.

My problem now is that I have to create 81 subviews (no problem), fill them with data from my model (no problem) and then add the whole grid to my layout (biiiig problem).

The whole building is done in a asynctask like this:

protected Void doInBackground(Void... params) {
    Model.Cell[][] sudoku = Controller.getInstance().startNewGame(); //call model for a new game
    ArrayList<TableRow> rows = ga.generateTable(sudoku); //generate the table
    tl = new TableLayout(ga); //create tablelayout
    //add the rows to the layout
    for (TableRow v : rows) {
        tl.addView(v);
    }

    return null;
}

Then after this is done:

protected void onPostExecute(Void result) {
    super.onPostExecute(result);

    RelativeLayout rl = (RelativeLayout) ga.findViewById(R.id.gridContainer); //get the container
    //create layout rules
    android.widget.RelativeLayout.LayoutParams params = new android.widget.RelativeLayout.LayoutParams(
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.CENTER_HORIZONTAL);
    //add the table to the container with the layout
    rl.addView(tl, params); //this is slow as hell.

    //stop loading indicator
    this.loading.dismiss();
}

I dont mind get a loading bar for a while. But my loading bar is stopping because rl.addView(tl, params) is superslow.

Can somebody please help me how to keep my main thread fast?

HansElsen
  • 1,639
  • 5
  • 27
  • 47
  • 1
    You have probably already considered this, but would it not be better just to use a SurfaceView and draw the cells and catch the touches manually? This use of many views seems like an overkill to me. – comodoro Sep 25 '12 at 15:16
  • @comodoro You are right that this would speed up the whole thing, but it would not contribute to the readability and scalability. – HansElsen Sep 25 '12 at 15:28
  • Well, that is a matter of opinion, I would go the obvious way, but it definitely depends on what you want to do with the code afterwards. It's your call :-) – comodoro Sep 25 '12 at 15:37
  • I agree with comodoro. Readability and scalability arises from your design, not neccesarily the implementation. For example. class PuzzleGrid{ private int mRows; private int mCols; public void setRows(), public void setCols(); public void setGridCells() } Perfectly readable, maintainable and scalable! Voila! IMHO, better than some loop creating views and adding to a layout. – Simon Sep 25 '12 at 15:41
  • The readability of my code will drop dramatically if I do what I think you're suggesting. I would have to create 81 little cells with each 10 labels (because thats how my cell looks like. Then change backgroundcolors border etc. – HansElsen Sep 25 '12 at 16:27
  • I tried to use SurfaceView as you said, but I cant figure out exactly how to draw on that surface. any suggestions? – HansElsen Sep 25 '12 at 16:55

2 Answers2

1

I believe the issue is you're adding a massive TableLayout in to a View. It has to go through measure and layout through every single one of the cells to fit it in to the layout.

One thing you can do is create the single TableLayout in onPreExecute and add it to the layout as such. Then, you can create each panel and add it to the TableLayout as they are being made. This would do all the layout stuff on a single cell rather than all of them in one large clump.

One thing that I'd like to point out that may-or-may not be related is you have one TableLayout created in a background thread. Inflating Views in a background thread has been known to cause problems on some devices. You're not inflating. You're creating a View object so it most likely is not the same, but I guess there's no gaurantee. As such, I'd probably use the background thread to create and gather the data of each cell, then create and add the cell in onProgressUpdate which runs on the UI thread.

Community
  • 1
  • 1
DeeV
  • 35,865
  • 9
  • 108
  • 95
  • I will give it a try, I'll report back when I have results – HansElsen Sep 25 '12 at 15:30
  • Hi I implemented as you suggested, but no difference at all. It still stops the main UI thread. – HansElsen Sep 25 '12 at 16:24
  • I would think there would be some change in how the UI is hanging. If rl.adView was causing the problems, then it would hang just before you started the thread. If you're still hanging in onPostExecute() then that might indicate another problem since you're no longer adding the tablelayout there. – DeeV Sep 25 '12 at 17:35
  • lets put it this way: when I comment that particular line, it is super fast. when I uncomment it, it is slow again. – HansElsen Sep 25 '12 at 17:55
0

I figured out that a tablelayout in combination with tablerows is very slow. I tried to use Horizontal and VerticalLinearlayouts and this improved the speed of generating the views by 300% at least.

Thanks for all the new tips. I'll consider them in the future!

HansElsen
  • 1,639
  • 5
  • 27
  • 47