如何有效地更新Android文本视图?

时间:2011-12-19 02:41:47

标签: android performance textview

我正在开发一款遇到性能问题的Android应用。 我的目标是从AsyncTask接收字符串并在TextView中显示它们。 TextView最初是空的,每次其他进程发送字符串时,它都会将其连接到textview的当前内容。 我目前使用StringBuilder存储主字符串,每次收到一个新字符串时,我将它附加到StringBuilder并调用

myTextView.setText(myStringBuilder.toString())

问题是后台进程每秒最多可以发送100个字符串,而且我的方法效率不高。

每次重绘整个TextView显然是一个坏主意(时间复杂度为O(N²)),但我没有看到另一种解决方案......

你知道TextView的替代方法可以在O(N)中进行这些连接吗?

3 个答案:

答案 0 :(得分:2)

只要字符串之间有换行符,就可以使用ListView追加字符串并将字符串本身保存在您附加的ArrayList或LinkedList中,因为AsyncTask接收字符串。

您可能还会考虑简单地使TextField无效;说一遍10次。这肯定会提高响应能力。像下面这样的东西可以工作:

static long lastTimeUpdated = 0;
if( receivedString.size() > 0 )
{
   myStringBuilder.append( receivedString );
}
if( (System.currentTimeMillis() - lastTimeUpdated) > 100 )
{
    myTextView.setText( myStringBuilder.getChars( 0, myStringBuilder.length() );
}

如果字符串突然出现 - 这样你的突发之间的延迟大于,比如一秒钟 - 那么每次更新时都会重置一个计时器,这会触发这个代码再次运行以获取后续部分最后爆发。

答案 1 :(得分:2)

我终于在这里找到了一个有问题的答案,这里有一些代码here。 随着字符串突然爆发,我选择每100毫秒更新一次UI。 为了记录,这是我的代码的样子:

private static boolean output_upToDate = true;

/* Handles the refresh */
private Handler outputUpdater = new Handler();

/* Adjust this value for your purpose */
public static final long REFRESH_INTERVAL = 100;      // in milliseconds

/* This object is used as a lock to avoid data loss in the last refresh */
private static final Object lock = new Object();


private Runnable outputUpdaterTask = new Runnable() {

    public void run() {
        // takes the lock
        synchronized(lock){
            if(!output_upToDate){
                // updates the outview
                outView.setText(new_text);
                // notifies that the output is up-to-date
                output_upToDate = true;
            }
        }
        outputUpdater.postDelayed(this, REFRESH_INTERVAL);
    }

 };

我把它放在我的onCreate()方法中:

outputUpdater.post(outputUpdaterTask);

一些解释:当我的应用调用其onCreate()方法时,我的outputUpdater处理程序会收到一个请求进行刷新。但是这个任务(outputUpdaterTask)在100ms之后就会发出刷新请求。 lock与发送新字符串并将output_upToDate设置为false的进程共享。

答案 2 :(得分:1)

尝试限制更新。因此,不是每秒更新100次,因为这是生成速度。将100个字符串保留在字符串构建器中,然后每秒更新一次。

代码应该:

StringBuilder completeStr = new StringBuilder();
StringBuilder new100Str = new StringBuilder();
int counter = 0;

if(counter < 100) {
  new100Str.append(newString);
  counter++;
} else {
  counter = 0;
  completeStr.append(new100Str);
  new100Str = new StringBuilder();
  myTextView.setText(completeStr.toString());
}

注意:上面的代码仅用于说明,因此您可能需要根据需要进行更改。