1

私のプログラムは、 GridView に CursorAdapter を使用し、 AsynTask を使用して curosr を取得し、ビューを更新します。

タスクの doinbackgroud で、sqlite でクエリを実行し、カーソルを取得します。タスクの onPostExecute では、 CursorAdapter.changeCursor を使用してビューを新しいデータで更新します。

しかし、カーソルには数千行のデータが多すぎるため、changeCursor のときに UI スレッドがブロックされました。

カーソルは怠惰な戦略を使用していませんか? どうすればいいですか?

私のコード:

private class ToNodeTask extends AsyncTask<Long, Void , OrgManager.CursorDataInfoInStruct >{

    protected Long taskId = null;

    @Override
    protected  OrgManager.CursorDataInfoInStruct doInBackground(Long... params) {
        taskId = params[0];
        OrgManager.CursorDataInfoInStruct info = OrgManager.getInstance().getCursorDataInfoInStruct(taskId);
        if(info != null){
            if(info.members != null){
                info.members.getCount();
            }
            if(info.nodes != null){
                info.nodes.getCount();
            }
        }

        return info;
    }

    @Override
    protected void onPostExecute( OrgManager.CursorDataInfoInStruct result) {
        super.onPostExecute(result);

        if(result != null){

            gridAdapter.changeCursor(result.members);
            departmentAdapter.changeCursor(result.nodes);
        }

    }

}

//OrgManager.java

public CursorDataInfoInStruct getCursorDataInfoInStruct(long structId){
        OrgStruct struct = getStruct(structId);
        if(null == struct && structId != 0) return null;

        CursorDataInfoInStruct info = new CursorDataInfoInStruct();
        info.parent = struct;
        info.nodes = getDb().rawQuery(SQL_QUERY_NODE_DATA_IN_SRUCT, new String[]{String.valueOf(structId)});
        info.members = getDb().rawQuery(SQL_QUERY_MEMBER_DATA_IN_SRUCT ,  new String[]{String.valueOf(structId)});

        return info;
    }

info.members と info.no​​des のクラスは Cursor です。

info.members に約 2000 行ある場合、デバイスで ui スレッドが約 4 秒間ブロックされます。作業スレッドで cursor.getCount() を呼び出しますが、役に立ちません。

4

2 に答える 2

1

大量のデータについては、ListView アダプタでの Cursor の使用を参照してください。

changeCursor を使用すると、 Cursor.getCount() が呼び出されます - 「これにより、クエリが完全に実行され、結果がカウントされます」。

私はそうしました-バックグラウンドスレッドでカーソルを準備し、その長さを取得します(dbからの抽出データはここで実行されます):

stopManagingCursor(cursor);
cursor = dbAdapter.getData(query);
startManagingCursor(cursor);
count = cursor.getCount();

UI スレッド (onPostExecute) でカーソルを変更します。

recordsAdapter.changeCursor(cursor);

この場合、カーソルを変更しても UI スレッドはフリーズしません。

于 2013-11-20T09:58:58.270 に答える