2011-12-19 13 views
4

パフォーマンスに関する問題が発生したAndroidアプリを開発中です。 私の目標は、AsyncTaskから文字列を受け取ってTextViewに表示することです。 TextViewは最初は空で、他のプロセスが文字列を送信するたびに、テキストビューの現在の内容に文字列を連結します。 私は現在、主な文字列を格納するためのStringBuilderを使用して、私は新しい文字列を受け取るたびに、私はStringBuilderのにそれを追加し、Androidのテキストビューを効率的に更新するには?

myTextView.setText(myStringBuilder.toString()) 

を呼び出す問題は、バックグラウンド・プロセスは、毎秒100列まで送ることができるということです私の方法は十分に効率的ではありません。全体のTextView毎回の再描画

は明らかに悪い考え(時間計算量O(N²))ですが、私は別のソリューションを見ていないよ...

あなたはこれらを行うことができますのTextViewの代替の知っていますかO(N)の連結

答えて

2

私は最終的にhavexzとGreysonの助けを借りて答えを見つけました。いくつかのコードはhereです。 文字列がバースト的になってきたので、UIを100msごとに更新することにしました。レコードの は、ここに私のコードは次のようになります。

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

文字列間に改行がある限り、ListViewを使用して文字列を追加し、AsyncTaskが文字列を受け取るときに追加するArrayListまたはLinkedListに文字列を保持することができます。

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

更新プログラムを調整してみます。そのため、世代ごとに100回更新するのではなく、世代ごとに更新するのではなく、文字列ビルダーに100文字列を保存してから、1秒に1回更新します。

コードは次のようにする必要があります

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

注:あなたがあなたのニーズに従って、それを変更する必要がある場合がありますので、上記のコードは、単に例示のためのものです。

関連する問題