Android TableLayout with over 1000 rows loading very slowly

核能气质少年 提交于 2019-12-07 23:10:14

问题


I'm looking for a way to speed up the creation of a TableLayout with over 1000 rows. Is there a way to create a TableLayout entirely on a separate thread or a way to speed it up?

Here is my method that is creating the table:

private void setTable()
{       
    final Activity activity = this;

    final Handler handler = new Handler();

    new Thread(new Runnable()
    {
        @Override
        public void run() 
        {
            for (int x = 0; x < rooms.size(); x++)
            {
                final int inx = x;
                handler.post(new Runnable()
                {
                    @Override
                    public void run() 
                    {
                        Methods.createRow(table, rooms.get(inx), null, activity);
                        TableRow row = (TableRow)table.getChildAt(inx);
                        row.setOnClickListener(new OnClickListener()
                        {
                            @Override
                            public void onClick(View arg0) 
                            {
                                if (arg0.getTag() != null && arg0.getTag().getClass() == Integer.class)
                                    select((Integer)arg0.getTag());
                            }
                        });
                    }
                });
            }
        }

    }).start();
}

I was hoping that using a Handler would at least allow the new Activity to appear before the table was created. The application seems to freeze up for a few seconds when creating tables with a lot of rows. setTable() is being run in my Activity's onStart() method.

Methods.createRow adds a row to the end of the TableView that is passed in.

Edit:

After deciding to try out a ListView, I got much better results with a lot less code.

private void setTable()
{
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, roomNames);
    table.setAdapter(adapter);
    table.setOnItemClickListener(new OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) 
        {
            select(arg2);
        }
    });
}

回答1:


First things first.

Why your app freezes: Handler works like a queue, it queues every post you made and than execute it serially in your main thread.

But the main problem is the amount of data you are trying to show at once, but it is easily solved with an Adapter, you probably can use some default Component for solve this, like ListView or GridView, you can make your custom rows to work around the columns maybe.




回答2:


Just from guessing on the method name, it seems this line may be slow to run on the main/UI thread: Methods.createRow(table, rooms.get(inx), null, activity);

I would suggest separating all the heavy database work and UI work with AsyncTask, so it might look something like this:

private OnClickListener rowClickListener = new OnClickListener()
{
    @Override
    public void onClick(View arg0) 
    {
        if (arg0.getTag() != null && arg0.getTag().getClass() == Integer.class)
            select((Integer)arg0.getTag());
    }
};

private void setTable()
{       
    final Activity activity = this;

    final Handler handler = new Handler();

    new AsyncTask<Void, Void, List<TableRow>>() {
        @Override
        protected List<TableRow> doInBackground(Void... params) {
            // Do all heavy work here
            final List<TableRow> rows = new ArrayList<TableRow>(rooms.size());
            for (int x = 0; x < rooms.size(); x++)
            {
                Methods.createRow(table, rooms.get(x), null, activity);
                rows.add((TableRow)table.getChildAt(x));
            }
            return rows;
        }

        @Override
        protected void onPreExecute() {
            // maybe show progress indication
        }

        @Override
        protected void onPostExecute(List<TableRow> result) {
            // Do all UI related actions here (maybe hide progress indication)
            for (final TableRow row : result) {
                row.setOnClickListener(rowClickListener);
            }
        }
    };
}

Since I can't tell what is in some methods, you'll just need to ensure you've tried to optimize as best as possible in Methods.createRow(...) and move all the UI related work to the onPostExecute(...) method.




回答3:


You are stacking the post with all the actions at once. So it same as not using a thread at all as your main thread doing all the work. Try changing to postDelay, and for each room index give it 1 millisecond or more.



来源:https://stackoverflow.com/questions/24539559/android-tablelayout-with-over-1000-rows-loading-very-slowly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!