问题
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