Preventing cursor leaks when a query is interrupted
Re-ran runtest cts-os Change-Id: I518a2a4f842b01d082078e16643aa377a4575237
This commit is contained in:
@@ -20,15 +20,19 @@ import android.os.AsyncTask;
|
||||
|
||||
/**
|
||||
* Abstract Loader that provides an {@link AsyncTask} to do the work.
|
||||
*
|
||||
*
|
||||
* @param <D> the data type to be loaded.
|
||||
*/
|
||||
public abstract class AsyncTaskLoader<D> extends Loader<D> {
|
||||
final class LoadTask extends AsyncTask<Void, Void, D> {
|
||||
|
||||
private D result;
|
||||
|
||||
/* Runs on a worker thread */
|
||||
@Override
|
||||
protected D doInBackground(Void... params) {
|
||||
return AsyncTaskLoader.this.loadInBackground();
|
||||
result = AsyncTaskLoader.this.loadInBackground();
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Runs on the UI thread */
|
||||
@@ -36,6 +40,11 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> {
|
||||
protected void onPostExecute(D data) {
|
||||
AsyncTaskLoader.this.dispatchOnLoadComplete(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled() {
|
||||
AsyncTaskLoader.this.onCancelled(result);
|
||||
}
|
||||
}
|
||||
|
||||
LoadTask mTask;
|
||||
@@ -50,6 +59,7 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> {
|
||||
*/
|
||||
@Override
|
||||
public void forceLoad() {
|
||||
cancelLoad();
|
||||
mTask = new LoadTask();
|
||||
mTask.execute((Void[]) null);
|
||||
}
|
||||
@@ -65,11 +75,20 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> {
|
||||
*/
|
||||
public boolean cancelLoad() {
|
||||
if (mTask != null) {
|
||||
return mTask.cancel(false);
|
||||
boolean cancelled = mTask.cancel(false);
|
||||
mTask = null;
|
||||
return cancelled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called if the task was canceled before it was completed. Gives the class a chance
|
||||
* to properly dispose of the result.
|
||||
*/
|
||||
public void onCancelled(D data) {
|
||||
}
|
||||
|
||||
void dispatchOnLoadComplete(D data) {
|
||||
mTask = null;
|
||||
deliverResult(data);
|
||||
@@ -78,7 +97,7 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> {
|
||||
/**
|
||||
* Called on a worker thread to perform the actual load. Implementations should not deliver the
|
||||
* results directly, but should return them from this method, which will eventually end up
|
||||
* calling deliverResult on the UI thread. If implementations need to process
|
||||
* calling deliverResult on the UI thread. If implementations need to process
|
||||
* the results on the UI thread they may override deliverResult and do so
|
||||
* there.
|
||||
*
|
||||
|
||||
@@ -71,7 +71,7 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> {
|
||||
/**
|
||||
* Starts an asynchronous load of the contacts list data. When the result is ready the callbacks
|
||||
* will be called on the UI thread. If a previous load has been completed and is still valid
|
||||
* the result may be passed to the callbacks immediately.
|
||||
* the result may be passed to the callbacks immediately.
|
||||
*
|
||||
* Must be called from the UI thread
|
||||
*/
|
||||
@@ -103,6 +103,13 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> {
|
||||
mStopped = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(Cursor cursor) {
|
||||
if (cursor != null && !cursor.isClosed()) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// Ensure the loader is stopped
|
||||
|
||||
@@ -187,6 +187,17 @@ public abstract class AsyncTask<Params, Progress, Result> {
|
||||
};
|
||||
|
||||
mFuture = new FutureTask<Result>(mWorker) {
|
||||
|
||||
@Override
|
||||
protected void set(Result v) {
|
||||
super.set(v);
|
||||
if (isCancelled()) {
|
||||
Message message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
|
||||
new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
|
||||
message.sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
Message message;
|
||||
@@ -401,7 +412,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
|
||||
* publish updates on the UI thread while the background computation is
|
||||
* still running. Each call to this method will trigger the execution of
|
||||
* {@link #onProgressUpdate} on the UI thread.
|
||||
*
|
||||
*
|
||||
* {@link #onProgressUpdate} will note be called if the task has been
|
||||
* canceled.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user