Android TableLayout加载超过1000行非常慢

时间:2014-07-02 19:33:15

标签: android multithreading tablelayout

我正在寻找一种方法来加速创建超过1000行的TableLayout。有没有办法完全在一个单独的线程上创建一个TableLayout或一种加速它的方法?

这是我创建表格的方法:

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();
}

我希望使用Handler至少允许新的Activity在创建表之前出现。在创建包含大量行的表时,应用程序似乎会冻结几秒钟。 setTable()正在我的Activity的onStart()方法中运行。

Methods.createRow在传入的TableView末尾添加一行。

修改

在决定试用ListView之后,我用更少的代码获得了更好的结果。

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);
        }
    });
}

3 个答案:

答案 0 :(得分:4)

首先要做的事情。

为什么你的应用会冻结: Handler的工作方式类似于队列,它会对您发布的每个帖子进行排队,而不是在主线程中以串行方式执行。

但主要问题是您尝试同时显示的数据量,但可以使用适配器轻松解决,您可能可以使用一些默认组件来解决此问题,例如ListView或{{3你可以让你的自定义行来处理列。

答案 1 :(得分:0)

仅仅猜测方法名称,似乎这条线在主/ UI线程上运行起来可能很慢:     Methods.createRow(table,rooms.get(inx),null,activity);

我建议将所有繁重的数据库工作和UI工作与AsyncTask分开,所以它可能看起来像这样:

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);
            }
        }
    };
}

由于我无法分辨某些方法中的内容,因此您只需确保尝试在Methods.createRow(...)中尽可能优化并将所有与UI相关的工作移至onPostExecute(...)方法。

答案 2 :(得分:-1)

您正在使用所有操作一次堆叠帖子。因此,完全不使用线程作为主线程完成所有工作。尝试更改为postDelay,并为每个房间索引提供1毫秒或更长时间。