下面列出了android.os.CancellationSignal#throwIfCanceled ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* This allows clients to request an explicit refresh of content identified by {@code uri}.
* <p>
* Client code should only invoke this method when there is a strong indication (such as a user
* initiated pull to refresh gesture) that the content is stale.
* <p>
*
* @param url The Uri identifying the data to refresh.
* @param args Additional options from the client. The definitions of these are specific to the
* content provider being called.
* @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if
* none. For example, if you called refresh on a particular uri, you should call
* {@link CancellationSignal#throwIfCanceled()} to check whether the client has
* canceled the refresh request.
* @return true if the provider actually tried refreshing.
*/
public final boolean refresh(@NonNull Uri url, @Nullable Bundle args,
@Nullable CancellationSignal cancellationSignal) {
Preconditions.checkNotNull(url, "url");
IContentProvider provider = acquireProvider(url);
if (provider == null) {
return false;
}
try {
ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
remoteCancellationSignal = provider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
return provider.refresh(mPackageName, url, args, remoteCancellationSignal);
} catch (RemoteException e) {
// Arbitrary and not worth documenting, as Activity
// Manager will kill this process shortly anyway.
return false;
} finally {
releaseProvider(provider);
}
}
/**
* Performs special reinterpretation of certain SQL statements such as "BEGIN",
* "COMMIT" and "ROLLBACK" to ensure that transaction state invariants are
* maintained.
*
* This function is mainly used to support legacy apps that perform their
* own transactions by executing raw SQL rather than calling {@link #beginTransaction}
* and the like.
*
* @param sql The SQL statement to execute.
* @param bindArgs The arguments to bind, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
* @param cancellationSignal A signal to cancel the operation in progress, or null if none.
* @return True if the statement was of a special form that was handled here,
* false otherwise.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
private boolean executeSpecial(String sql, Object[] bindArgs, int connectionFlags,
CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
final int type = DatabaseUtils.getSqlStatementType(sql);
switch (type) {
case DatabaseUtils.STATEMENT_BEGIN:
beginTransaction(TRANSACTION_MODE_EXCLUSIVE, null, connectionFlags,
cancellationSignal);
return true;
case DatabaseUtils.STATEMENT_COMMIT:
setTransactionSuccessful();
endTransaction(cancellationSignal);
return true;
case DatabaseUtils.STATEMENT_ABORT:
endTransaction(cancellationSignal);
return true;
}
return false;
}
/**
* This allows clients to request an explicit refresh of content identified by {@code uri}.
* <p>
* Client code should only invoke this method when there is a strong indication (such as a user
* initiated pull to refresh gesture) that the content is stale.
* <p>
*
* @param url The Uri identifying the data to refresh.
* @param args Additional options from the client. The definitions of these are specific to the
* content provider being called.
* @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if
* none. For example, if you called refresh on a particular uri, you should call
* {@link CancellationSignal#throwIfCanceled()} to check whether the client has
* canceled the refresh request.
* @return true if the provider actually tried refreshing.
*/
public final boolean refresh(@NonNull Uri url, @Nullable Bundle args,
@Nullable CancellationSignal cancellationSignal) {
Preconditions.checkNotNull(url, "url");
IContentProvider provider = acquireProvider(url);
if (provider == null) {
return false;
}
try {
ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
remoteCancellationSignal = provider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
return provider.refresh(mPackageName, url, args, remoteCancellationSignal);
} catch (RemoteException e) {
// Arbitrary and not worth documenting, as Activity
// Manager will kill this process shortly anyway.
return false;
} finally {
releaseProvider(provider);
}
}
/** See {@link ContentProvider#refresh} */
public boolean refresh(Uri url, @Nullable Bundle args,
@Nullable CancellationSignal cancellationSignal) throws RemoteException {
Preconditions.checkNotNull(url, "url");
beforeRemote();
try {
ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
remoteCancellationSignal = mContentProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
return mContentProvider.refresh(mPackageName, url, args, remoteCancellationSignal);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
}
throw e;
} finally {
afterRemote();
}
}
/**
* See {@link ContentProvider#openFile ContentProvider.openFile}. Note that
* this <em>does not</em>
* take care of non-content: URIs such as file:. It is strongly recommended
* you use the {@link ContentResolver#openFileDescriptor
* ContentResolver.openFileDescriptor} API instead.
*/
public @Nullable ParcelFileDescriptor openFile(@NonNull Uri url, @NonNull String mode,
@Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
Preconditions.checkNotNull(url, "url");
Preconditions.checkNotNull(mode, "mode");
beforeRemote();
try {
ICancellationSignal remoteSignal = null;
if (signal != null) {
signal.throwIfCanceled();
remoteSignal = mContentProvider.createCancellationSignal();
signal.setRemote(remoteSignal);
}
return mContentProvider.openFile(mPackageName, url, mode, remoteSignal, null);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
}
throw e;
} finally {
afterRemote();
}
}
/**
* See {@link ContentProvider#openAssetFile ContentProvider.openAssetFile}.
* Note that this <em>does not</em>
* take care of non-content: URIs such as file:. It is strongly recommended
* you use the {@link ContentResolver#openAssetFileDescriptor
* ContentResolver.openAssetFileDescriptor} API instead.
*/
public @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri url, @NonNull String mode,
@Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
Preconditions.checkNotNull(url, "url");
Preconditions.checkNotNull(mode, "mode");
beforeRemote();
try {
ICancellationSignal remoteSignal = null;
if (signal != null) {
signal.throwIfCanceled();
remoteSignal = mContentProvider.createCancellationSignal();
signal.setRemote(remoteSignal);
}
return mContentProvider.openAssetFile(mPackageName, url, mode, remoteSignal);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
}
throw e;
} finally {
afterRemote();
}
}
/** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
public final @Nullable AssetFileDescriptor openTypedAssetFileDescriptor(@NonNull Uri uri,
@NonNull String mimeType, @Nullable Bundle opts, @Nullable CancellationSignal signal)
throws RemoteException, FileNotFoundException {
Preconditions.checkNotNull(uri, "uri");
Preconditions.checkNotNull(mimeType, "mimeType");
beforeRemote();
try {
ICancellationSignal remoteSignal = null;
if (signal != null) {
signal.throwIfCanceled();
remoteSignal = mContentProvider.createCancellationSignal();
signal.setRemote(remoteSignal);
}
return mContentProvider.openTypedAssetFile(
mPackageName, uri, mimeType, opts, remoteSignal);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
}
throw e;
} finally {
afterRemote();
}
}
/**
* Performs special reinterpretation of certain SQL statements such as "BEGIN",
* "COMMIT" and "ROLLBACK" to ensure that transaction state invariants are
* maintained.
*
* This function is mainly used to support legacy apps that perform their
* own transactions by executing raw SQL rather than calling {@link #beginTransaction}
* and the like.
*
* @param sql The SQL statement to execute.
* @param bindArgs The arguments to bind, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
* @param cancellationSignal A signal to cancel the operation in progress, or null if none.
* @return True if the statement was of a special form that was handled here,
* false otherwise.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
private boolean executeSpecial(String sql, Object[] bindArgs, int connectionFlags,
CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
final int type = DatabaseUtils.getSqlStatementType(sql);
switch (type) {
case DatabaseUtils.STATEMENT_BEGIN:
beginTransaction(TRANSACTION_MODE_EXCLUSIVE, null, connectionFlags,
cancellationSignal);
return true;
case DatabaseUtils.STATEMENT_COMMIT:
setTransactionSuccessful();
endTransaction(cancellationSignal);
return true;
case DatabaseUtils.STATEMENT_ABORT:
endTransaction(cancellationSignal);
return true;
}
return false;
}
private void attachCancellationSignal(CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
mCancellationSignalAttachCount += 1;
if (mCancellationSignalAttachCount == 1) {
// Reset cancellation flag before executing the statement.
nativeResetCancel(mConnectionPtr, true /*cancelable*/);
// After this point, onCancel() may be called concurrently.
cancellationSignal.setOnCancelListener(this);
}
}
}
private boolean yieldTransactionUnchecked(long sleepAfterYieldDelayMillis,
CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
if (!mConnectionPool.shouldYieldConnection(mConnection, mConnectionFlags)) {
return false;
}
final int transactionMode = mTransactionStack.mMode;
final SQLiteTransactionListener listener = mTransactionStack.mListener;
final int connectionFlags = mConnectionFlags;
endTransactionUnchecked(cancellationSignal, true); // might throw
if (sleepAfterYieldDelayMillis > 0) {
try {
Thread.sleep(sleepAfterYieldDelayMillis);
} catch (InterruptedException ex) {
// we have been interrupted, that's all we need to do
}
}
beginTransactionUnchecked(transactionMode, listener, connectionFlags,
cancellationSignal); // might throw
return true;
}
/** See {@link ContentProvider#query ContentProvider.query} */
public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection,
Bundle queryArgs, @Nullable CancellationSignal cancellationSignal)
throws RemoteException {
Preconditions.checkNotNull(uri, "url");
beforeRemote();
try {
ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
remoteCancellationSignal = mContentProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
final Cursor cursor = mContentProvider.query(
mPackageName, uri, projection, queryArgs, remoteCancellationSignal);
if (cursor == null) {
return null;
}
return new CursorWrapperInner(cursor);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
}
throw e;
} finally {
afterRemote();
}
}
private void attachCancellationSignal(CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
mCancellationSignalAttachCount += 1;
if (mCancellationSignalAttachCount == 1) {
// Reset cancellation flag before executing the statement.
nativeResetCancel(mConnectionPtr, true /*cancelable*/);
// After this point, onCancel() may be called concurrently.
cancellationSignal.setOnCancelListener(this);
}
}
}
private boolean yieldTransactionUnchecked(long sleepAfterYieldDelayMillis,
CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
if (!mConnectionPool.shouldYieldConnection(mConnection, mConnectionFlags)) {
return false;
}
final int transactionMode = mTransactionStack.mMode;
final SQLiteTransactionListener listener = mTransactionStack.mListener;
final int connectionFlags = mConnectionFlags;
endTransactionUnchecked(cancellationSignal, true); // might throw
if (sleepAfterYieldDelayMillis > 0) {
try {
Thread.sleep(sleepAfterYieldDelayMillis);
} catch (InterruptedException ex) {
// we have been interrupted, that's all we need to do
}
}
beginTransactionUnchecked(transactionMode, listener, connectionFlags,
cancellationSignal); // might throw
return true;
}
private void beginTransactionUnchecked(int transactionMode,
SQLiteTransactionListener transactionListener, int connectionFlags,
CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
if (mTransactionStack == null) {
acquireConnection(null, connectionFlags, cancellationSignal); // might throw
}
try {
// Set up the transaction such that we can back out safely
// in case we fail part way.
if (mTransactionStack == null) {
// Execute SQL might throw a runtime exception.
switch (transactionMode) {
case TRANSACTION_MODE_IMMEDIATE:
mConnection.execute("BEGIN IMMEDIATE;", null,
cancellationSignal); // might throw
break;
case TRANSACTION_MODE_EXCLUSIVE:
mConnection.execute("BEGIN EXCLUSIVE;", null,
cancellationSignal); // might throw
break;
default:
mConnection.execute("BEGIN;", null, cancellationSignal); // might throw
break;
}
}
// Listener might throw a runtime exception.
if (transactionListener != null) {
try {
transactionListener.onBegin(); // might throw
} catch (RuntimeException ex) {
if (mTransactionStack == null) {
mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw
}
throw ex;
}
}
// Bookkeeping can't throw, except an OOM, which is just too bad...
Transaction transaction = obtainTransaction(transactionMode, transactionListener);
transaction.mParent = mTransactionStack;
mTransactionStack = transaction;
} finally {
if (mTransactionStack == null) {
releaseConnection(); // might throw
}
}
}
private void endTransactionUnchecked(CancellationSignal cancellationSignal, boolean yielding) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
final Transaction top = mTransactionStack;
boolean successful = (top.mMarkedSuccessful || yielding) && !top.mChildFailed;
RuntimeException listenerException = null;
final SQLiteTransactionListener listener = top.mListener;
if (listener != null) {
try {
if (successful) {
listener.onCommit(); // might throw
} else {
listener.onRollback(); // might throw
}
} catch (RuntimeException ex) {
listenerException = ex;
successful = false;
}
}
mTransactionStack = top.mParent;
recycleTransaction(top);
if (mTransactionStack != null) {
if (!successful) {
mTransactionStack.mChildFailed = true;
}
} else {
try {
if (successful) {
mConnection.execute("COMMIT;", null, cancellationSignal); // might throw
} else {
mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw
}
} finally {
releaseConnection(); // might throw
}
}
if (listenerException != null) {
throw listenerException;
}
}
/**
* Prepares a statement for execution but does not bind its parameters or execute it.
* <p>
* This method can be used to check for syntax errors during compilation
* prior to execution of the statement. If the {@code outStatementInfo} argument
* is not null, the provided {@link SQLiteStatementInfo} object is populated
* with information about the statement.
* </p><p>
* A prepared statement makes no reference to the arguments that may eventually
* be bound to it, consequently it it possible to cache certain prepared statements
* such as SELECT or INSERT/UPDATE statements. If the statement is cacheable,
* then it will be stored in the cache for later and reused if possible.
* </p>
*
* @param sql The SQL statement to prepare.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
* @param cancellationSignal A signal to cancel the operation in progress, or null if none.
* @param outStatementInfo The {@link SQLiteStatementInfo} object to populate
* with information about the statement, or null if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error.
* @throws OperationCanceledException if the operation was canceled.
*/
public void prepare(String sql, int connectionFlags, CancellationSignal cancellationSignal,
SQLiteStatementInfo outStatementInfo) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
mConnection.prepare(sql, outStatementInfo); // might throw
} finally {
releaseConnection(); // might throw
}
}
private void beginTransactionUnchecked(int transactionMode,
SQLiteTransactionListener transactionListener, int connectionFlags,
CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
if (mTransactionStack == null) {
acquireConnection(null, connectionFlags, cancellationSignal); // might throw
}
try {
// Set up the transaction such that we can back out safely
// in case we fail part way.
if (mTransactionStack == null) {
// Execute SQL might throw a runtime exception.
switch (transactionMode) {
case TRANSACTION_MODE_IMMEDIATE:
mConnection.execute("BEGIN IMMEDIATE;", null,
cancellationSignal); // might throw
break;
case TRANSACTION_MODE_EXCLUSIVE:
mConnection.execute("BEGIN EXCLUSIVE;", null,
cancellationSignal); // might throw
break;
default:
mConnection.execute("BEGIN;", null, cancellationSignal); // might throw
break;
}
}
// Listener might throw a runtime exception.
if (transactionListener != null) {
try {
transactionListener.onBegin(); // might throw
} catch (RuntimeException ex) {
if (mTransactionStack == null) {
mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw
}
throw ex;
}
}
// Bookkeeping can't throw, except an OOM, which is just too bad...
Transaction transaction = obtainTransaction(transactionMode, transactionListener);
transaction.mParent = mTransactionStack;
mTransactionStack = transaction;
} finally {
if (mTransactionStack == null) {
releaseConnection(); // might throw
}
}
}
private void endTransactionUnchecked(CancellationSignal cancellationSignal, boolean yielding) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
final Transaction top = mTransactionStack;
boolean successful = (top.mMarkedSuccessful || yielding) && !top.mChildFailed;
RuntimeException listenerException = null;
final SQLiteTransactionListener listener = top.mListener;
if (listener != null) {
try {
if (successful) {
listener.onCommit(); // might throw
} else {
listener.onRollback(); // might throw
}
} catch (RuntimeException ex) {
listenerException = ex;
successful = false;
}
}
mTransactionStack = top.mParent;
recycleTransaction(top);
if (mTransactionStack != null) {
if (!successful) {
mTransactionStack.mChildFailed = true;
}
} else {
try {
if (successful) {
mConnection.execute("COMMIT;", null, cancellationSignal); // might throw
} else {
mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw
}
} finally {
releaseConnection(); // might throw
}
}
if (listenerException != null) {
throw listenerException;
}
}
/**
* Prepares a statement for execution but does not bind its parameters or execute it.
* <p>
* This method can be used to check for syntax errors during compilation
* prior to execution of the statement. If the {@code outStatementInfo} argument
* is not null, the provided {@link SQLiteStatementInfo} object is populated
* with information about the statement.
* </p><p>
* A prepared statement makes no reference to the arguments that may eventually
* be bound to it, consequently it it possible to cache certain prepared statements
* such as SELECT or INSERT/UPDATE statements. If the statement is cacheable,
* then it will be stored in the cache for later and reused if possible.
* </p>
*
* @param sql The SQL statement to prepare.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
* @param cancellationSignal A signal to cancel the operation in progress, or null if none.
* @param outStatementInfo The {@link SQLiteStatementInfo} object to populate
* with information about the statement, or null if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error.
* @throws OperationCanceledException if the operation was canceled.
*/
public void prepare(String sql, int connectionFlags, CancellationSignal cancellationSignal,
SQLiteStatementInfo outStatementInfo) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
mConnection.prepare(sql, outStatementInfo); // might throw
} finally {
releaseConnection(); // might throw
}
}