FC2ブログ
管理人が気まぐれでいろいろ書きます。
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
ListViewの高速化
LapisStramのリリースを控え、機能追加よりも全体の安定性や、高速化などのチューニングに力を入れてる今日このごろです。

そのチューニングのテストの一つとして短時間に大量のツイートが流れてきた場合でも正しく動作するか確かめています。
そのテストでListviewにアイテムを追加する際に複数のスレッドから追加が行われると、アイテムが追加されるタイミングによっては表示するデータのリストに不整合が起こる問題がみつかりました。
ListViewとは一般的に電話の履歴や連絡先の表示などに利用されている、アイテムを縦に並べ表示、選択するUIです。
問題の解決方法としてListviewに表示するアイテムのListへの操作の同期を取りデータの編集を行う操作を排他制御することで不整合の発生を回避しました。

具体的に発生していた問題は次のとおりです。
発生した問題はBaseAdatper#notifydatasetchanged()を呼ぶとエラーで落ちてしまう問題です。
このとき出されるエラーは英文でちょろちょろ出てくるのですが、内容の要約は「UIスレッド外からListViewいじってない?UIスレッドからだけListViewAdapterへのアイテム追加して」みたいな内容が出てました。

原因としてListview内部で保持しているアイテム数とListViewAdapterのBaseAdapter#getItem()で返されるアイテム数が一致しないとエラーで落ちてしまうようです。

この問題の解決法として、ListViewAdapter内にアイテム数を保持する変数を用意し、notifydatasetchanged()をオーバーライドし、super.notifydatasetchanged()を読ぶ直前にその変数の値を実際のアイテム数と一致させ、getItem()で返す値はその変数の値を返すように実装します。
またnotifydatasetchanged()はsynchronized修飾子を付け、ほぼ同時にnotifydatasetchanged()が呼ばれて、他のスレッドがアイテム数を保持する変数を書き換えてしまうのを防ぎます。

こうすることでnotifydatasetchanged()の内部で取得されるgetitem()で返る値がnotifydatasetchanged()を呼ばれたタイミングでのListView内部で保持するアイテム数の値から変わってしまうというのを防げるので問題を解決できます。
スポンサーサイト
コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。