我正在开发一款遇到性能问题的Android应用。 我的目标是从AsyncTask接收字符串并在TextView中显示它们。 TextView最初是空的,每次其他进程发送字符串时,它都会将其连接到textview的当前内容。 我目前使用StringBuilder存储主字符串,每次收到一个新字符串时,我将它附加到StringBuilder并调用
myTextView.setText(myStringBuilder.toString())
问题是后台进程每秒最多可以发送100个字符串,而且我的方法效率不高。
每次重绘整个TextView显然是一个坏主意(时间复杂度为O(N²)),但我没有看到另一种解决方案......
你知道TextView的替代方法可以在O(N)中进行这些连接吗?
答案 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());
}
注意:上面的代码仅用于说明,因此您可能需要根据需要进行更改。