본문 바로가기

안드로이드 개발

DB Query를 별도의 Thread로 처리하기

반응형

안드로이드에서 일반적으로 DB Query가 빠르다고 생각하고 MainThread에서 실행하는 경우가 대다수라고 생각한다. 데이터가 복잡하지 않거나 적은양일 경우에는 빠르게 처리되지만, 쿼비가 복잡하고 데이터가 많은 경우에는 ANR이 발생한다. ANR 방지를 위해 별도의 Thread로 쿼리를 처리해야한다. 별도의 Thead를 쓰기가 번거로움을 방지하기위해 안드로이드에서는 AsyncQueryHandler를 제공해주고 있다. 


public class AsyncQueryHelper extends AsyncQueryHandler {

    private WeakReference<notifyingasyncquerylistener> mListener;

    public interface NotifyingAsyncQueryListener {
        void onQueryComplete(int token, Object cookie, Cursor cursor);
    }

    public AsyncQueryHelper(ContentResolver resolver, NotifyingAsyncQueryListener listener) {
        super(resolver);
        setQueryListener(listener);
    }

    public void setQueryListener(NotifyingAsyncQueryListener listener) {
        mListener = (listener != null) ? new WeakReference<notifyingasyncquerylistener>(listener) : null;
    }
    
    public void clearQueryListener() {
        mListener = null;
    }

    public void startQuery(Uri uri, String[] projection) {
        startQuery(-1, null, uri, projection, null, null, null);
    }

    public void startQuery(Uri uri, String[] projection, String sortOrder) {
        startQuery(-1, null, uri, projection, null, null, sortOrder);
    }

    @Override
    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
        final NotifyingAsyncQueryListener listener = (mListener == null) ? null : mListener.get();
        if (listener != null) {
            listener.onQueryComplete(token, cookie, cursor);
        } else if (cursor != null) {
            cursor.close();
        }
    }
}


이렇게 Helper를 만들고 아래와 같이 쿼리를 하면된다. Listener를 통해 쿼리가 완료되는 시점도 알 수 있다.  


private AsyncQueryHelper mAsyncQueryHelper;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    ...
    
    mAsyncQueryHelper = new AsyncQueryHelper(getContentResolver(), this);
    mAsyncQueryHelper.startQuery(Media.EXTERNAL_CONTENT_URI, AudioFilesQuery.PROJECTION, AudioFilesQuery.SORT_ORDER);
}

@Override
public void onQueryComplete(int token, Object cookie, Cursor cursor) {
    if (cursor != null) {
        startManagingCursor(cursor);
    }
    mAdapter.changeCursor(cursor);
}




반응형