1

を使用して視覚化したい数千行を返す SQLite クエリがありますListView

UI スレッドの応答性を維持するためListAdapterに、バックグラウンド スレッドで を作成します。

ただし、最も時間がかかる (そして ANR を引き起こす可能性がある) ステートメントはListActivity.setListAdapter、UI スレッドで実行する必要があるステートメントです...何かアドバイスはありますか?

public class CursorTestActivity extends ListActivity {

    private static final String LOGTAG = "DBTEST";

    プライベート DatabaseManager mDbManager;
    プライベート Cursor mCursor;
    プライベート HandlerThread mIOWorkerThread;
    プライベート ハンドラ mIOHandler;
    プライベート ハンドラ mUIHandler;

    @オーバーライド
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mDbManager = 新しい DatabaseManager(this);

        mUIHandler = 新しいハンドラー();
        createIOWorkerThread();

        log("カーソルを作成中");
        mCursor = mDbManager.getCursor(); // db.query(...) を実行します
        startManagingCursor(mCursor);

        mIOHandler.post(new Runnable() {
            @オーバーライド
            public void run() {
                setMyListAdapter();
            }
        });
        log("onCreate 完了");
    }

    プライベートボイドsetMyListAdapter(){
        log("アダプタの構築");
        // CustomCursorAdapter は bindView と newView を実装します
        final CustomCursorAdapter listAdapter = new CustomCursorAdapter(this,
                mCursor、false);
        log("アダプタの構築が完了しました");
        mUIHandler.post(new Runnable() {
            @オーバーライド
            public void run() {
                log("設定一覧アダプタ");
                setListAdapter(listAdapter); // 返される行が増えるほど遅くなります
                log("設定内容表示");
                setContentView(R.layout.main);
                log("コンテンツビューの設定完了");
            }
        });
    }

    プライベートボイド createIOWorkerThread() {
        mIOWorkerThread = new HandlerThread("io_thread");
        mIOWorkerThread.start();
        ルーパー looper = mIOWorkerThread.getLooper();
        mIOHandler = new Handler(ルーパー);
    }

    private void destroyIOWorkerThread() {
        if (mIOWorkerThread == null)
            戻る;
        ルーパー looper = mIOWorkerThread.getLooper();
        if (ルーパー != null) {
            looper.quit();
        }
    }

    @オーバーライド
    public void onDestroy() {
        super.onDestroy();
        もし (mDbManager != null)
            mDbManager.close();
        destroyIOWorkerThread();
    }

    プライベート スタティック ボイド ログ(文字列 s) {
        Log.d(LOGTAG, s);
    }

}
4

2 に答える 2

0

カーソルは遅延ロードされるため、最初のデータ アクセスでカーソルがロードされます - getCount はそのようなアクセスです。setAdapter メソッドがカーソルで getCount を呼び出しています - パフォーマンスの問題があります。

  • アダプターに空のカーソルを設定し、カーソルの読み込み中に空のリストを表示できます。次に、アダプターで changeCursor メソッドを使用して、カーソルを新しいものに変更します。
  • たとえば、最初のクエリで最初に 100 行をフェッチしてから、バックグラウンドでさらに行をロードし、Cursor を新しい行に変更できます。
  • または、getCount の独自の実装を持つ Cursor の独自の実装を作成し、要求に応じて要求された行をフェッチすることもできます。
于 2011-05-14T20:12:42.190 に答える