5757 *
5858 * <p>The primary methods that need to be implemented are:
5959 * <ul>
60+ * <li>{@link #onCreate} which is called to initialize the provider</li>
6061 * <li>{@link #query} which returns data to the caller</li>
6162 * <li>{@link #insert} which inserts new data into the content provider</li>
6263 * <li>{@link #update} which updates existing data in the content provider</li>
6364 * <li>{@link #delete} which deletes data from the content provider</li>
6465 * <li>{@link #getType} which returns the MIME type of data in the content provider</li>
6566 * </ul></p>
6667 *
67- * <p>This class takes care of cross process calls so subclasses don't have to worry about which
68- * process a request is coming from.</p>
68+ * <p class="caution">Data access methods (such as {@link #insert} and
69+ * {@link #update}) may be called from many threads at once, and must be thread-safe.
70+ * Other methods (such as {@link #onCreate}) are only called from the application
71+ * main thread, and must avoid performing lengthy operations. See the method
72+ * descriptions for their expected thread behavior.</p>
73+ *
74+ * <p>Requests to {@link ContentResolver} are automatically forwarded to the appropriate
75+ * ContentProvider instance, so subclasses don't have to worry about the details of
76+ * cross-process calls.</p>
6977 */
7078public abstract class ContentProvider implements ComponentCallbacks {
7179 /*
@@ -81,6 +89,21 @@ public abstract class ContentProvider implements ComponentCallbacks {
8189
8290 private Transport mTransport = new Transport ();
8391
92+ /**
93+ * Construct a ContentProvider instance. Content providers must be
94+ * <a href="{@docRoot}guide/topics/manifest/provider-element.html">declared
95+ * in the manifest</a>, accessed with {@link ContentResolver}, and created
96+ * automatically by the system, so applications usually do not create
97+ * ContentProvider instances directly.
98+ *
99+ * <p>At construction time, the object is uninitialized, and most fields and
100+ * methods are unavailable. Subclasses should initialize themselves in
101+ * {@link #onCreate}, not the constructor.
102+ *
103+ * <p>Content providers are created on the application main thread at
104+ * application launch time. The constructor must not perform lengthy
105+ * operations, or application startup will be delayed.
106+ */
84107 public ContentProvider () {
85108 }
86109
@@ -328,8 +351,8 @@ private void enforceWritePermission(Uri uri) {
328351
329352
330353 /**
331- * Retrieve the Context this provider is running in. Only available once
332- * onCreate(Map icicle) has been called -- this will be null in the
354+ * Retrieves the Context this provider is running in. Only available once
355+ * {@link # onCreate} has been called -- this will return null in the
333356 * constructor.
334357 */
335358 public final Context getContext () {
@@ -403,23 +426,59 @@ public final PathPermission[] getPathPermissions() {
403426 }
404427
405428 /**
406- * Called when the provider is being started.
429+ * Implement this to initialize your content provider on startup.
430+ * This method is called for all registered content providers on the
431+ * application main thread at application launch time. It must not perform
432+ * lengthy operations, or application startup will be delayed.
433+ *
434+ * <p>You should defer nontrivial initialization (such as opening,
435+ * upgrading, and scanning databases) until the content provider is used
436+ * (via {@link #query}, {@link #insert}, etc). Deferred initialization
437+ * keeps application startup fast, avoids unnecessary work if the provider
438+ * turns out not to be needed, and stops database errors (such as a full
439+ * disk) from halting application launch.
440+ *
441+ * <p>For SQL databases, {@link android.database.sqlite.SQLiteOpenHelper}
442+ * is a helpful utility class that makes it easy to manage databases,
443+ * and will automatically defer opening until first use. If you do use
444+ * SQLiteOpenHelper, make sure to avoid calling
445+ * {@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} or
446+ * {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase}
447+ * from this method. (Instead, override
448+ * {@link android.database.sqlite.SQLiteOpenHelper#onOpen} to initialize the
449+ * database when it is first opened.)
407450 *
408451 * @return true if the provider was successfully loaded, false otherwise
409452 */
410453 public abstract boolean onCreate ();
411454
455+ /**
456+ * {@inheritDoc}
457+ * This method is always called on the application main thread, and must
458+ * not perform lengthy operations.
459+ *
460+ * <p>The default content provider implementation does nothing.
461+ * Override this method to take appropriate action.
462+ * (Content providers do not usually care about things like screen
463+ * orientation, but may want to know about locale changes.)
464+ */
412465 public void onConfigurationChanged (Configuration newConfig ) {
413466 }
414-
467+
468+ /**
469+ * {@inheritDoc}
470+ * This method is always called on the application main thread, and must
471+ * not perform lengthy operations.
472+ *
473+ * <p>The default content provider implementation does nothing.
474+ * Subclasses may override this method to take appropriate action.
475+ */
415476 public void onLowMemory () {
416477 }
417478
418479 /**
419- * Receives a query request from a client in a local process, and
420- * returns a Cursor. This is called internally by the {@link ContentResolver}.
421- * This method can be called from multiple
422- * threads, as described in
480+ * Implement this to handle query requests from clients.
481+ * This method can be called from multiple threads, as described in
423482 * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
424483 * Processes and Threads</a>.
425484 * <p>
@@ -476,11 +535,11 @@ public abstract Cursor query(Uri uri, String[] projection,
476535 String selection , String [] selectionArgs , String sortOrder );
477536
478537 /**
479- * Return the MIME type of the data at the given URI. This should start with
538+ * Implement this to handle requests for the MIME type of the data at the
539+ * given URI. The returned MIME type should start with
480540 * <code>vnd.android.cursor.item</code> for a single record,
481541 * or <code>vnd.android.cursor.dir/</code> for multiple items.
482- * This method can be called from multiple
483- * threads, as described in
542+ * This method can be called from multiple threads, as described in
484543 * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
485544 * Processes and Threads</a>.
486545 *
@@ -490,11 +549,10 @@ public abstract Cursor query(Uri uri, String[] projection,
490549 public abstract String getType (Uri uri );
491550
492551 /**
493- * Implement this to insert a new row.
552+ * Implement this to handle requests to insert a new row.
494553 * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
495554 * after inserting.
496- * This method can be called from multiple
497- * threads, as described in
555+ * This method can be called from multiple threads, as described in
498556 * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
499557 * Processes and Threads</a>.
500558 * @param uri The content:// URI of the insertion request.
@@ -504,12 +562,12 @@ public abstract Cursor query(Uri uri, String[] projection,
504562 public abstract Uri insert (Uri uri , ContentValues values );
505563
506564 /**
507- * Implement this to insert a set of new rows, or the default implementation will
508- * iterate over the values and call {@link #insert} on each of them.
565+ * Override this to handle requests to insert a set of new rows, or the
566+ * default implementation will iterate over the values and call
567+ * {@link #insert} on each of them.
509568 * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
510569 * after inserting.
511- * This method can be called from multiple
512- * threads, as described in
570+ * This method can be called from multiple threads, as described in
513571 * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
514572 * Processes and Threads</a>.
515573 *
@@ -526,13 +584,12 @@ public int bulkInsert(Uri uri, ContentValues[] values) {
526584 }
527585
528586 /**
529- * A request to delete one or more rows. The selection clause is applied when performing
530- * the deletion, allowing the operation to affect multiple rows in a
531- * directory.
587+ * Implement this to handle requests to delete one or more rows.
588+ * The implementation should apply the selection clause when performing
589+ * deletion, allowing the operation to affect multiple rows in a directory.
532590 * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
533591 * after deleting.
534- * This method can be called from multiple
535- * threads, as described in
592+ * This method can be called from multiple threads, as described in
536593 * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
537594 * Processes and Threads</a>.
538595 *
@@ -549,13 +606,12 @@ public int bulkInsert(Uri uri, ContentValues[] values) {
549606 public abstract int delete (Uri uri , String selection , String [] selectionArgs );
550607
551608 /**
552- * Update a content URI. All rows matching the optionally provided selection
553- * will have their columns listed as the keys in the values map with the
554- * values of those keys .
609+ * Implement this to update one or more rows.
610+ * The implementation should update all rows matching the selection
611+ * to set the columns according to the provided values map .
555612 * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
556613 * after updating.
557- * This method can be called from multiple
558- * threads, as described in
614+ * This method can be called from multiple threads, as described in
559615 * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
560616 * Processes and Threads</a>.
561617 *
@@ -570,18 +626,15 @@ public abstract int update(Uri uri, ContentValues values, String selection,
570626 String [] selectionArgs );
571627
572628 /**
573- * Open a file blob associated with a content URI.
574- * This method can be called from multiple
575- * threads, as described in
629+ * Override this to open a file blob associated with a content URI.
630+ * The default implementation always throws {@link FileNotFoundException}.
631+ * This method can be called from multiple threads, as described in
576632 * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
577633 * Processes and Threads</a>.
578- *
579- * <p>Returns a
580- * ParcelFileDescriptor, from which you can obtain a
581- * {@link java.io.FileDescriptor} for use with
582- * {@link java.io.FileInputStream}, {@link java.io.FileOutputStream}, etc.
583- * This can be used to store large data (such as an image) associated with
584- * a particular piece of content.
634+ *
635+ * <p>Returns a ParcelFileDescriptor, which is returned directly to the
636+ * caller. This way large data (such as images and documents) can be
637+ * returned without copying the content.
585638 *
586639 * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
587640 * their responsibility to close it when done. That is, the implementation
@@ -599,31 +652,35 @@ public abstract int update(Uri uri, ContentValues values, String selection,
599652 * no file associated with the given URI or the mode is invalid.
600653 * @throws SecurityException Throws SecurityException if the caller does
601654 * not have permission to access the file.
602- *
655+ *
603656 * @see #openAssetFile(Uri, String)
604657 * @see #openFileHelper(Uri, String)
605- */
658+ */
606659 public ParcelFileDescriptor openFile (Uri uri , String mode )
607660 throws FileNotFoundException {
608661 throw new FileNotFoundException ("No files supported by provider at "
609662 + uri );
610663 }
611-
664+
612665 /**
613666 * This is like {@link #openFile}, but can be implemented by providers
614667 * that need to be able to return sub-sections of files, often assets
615- * inside of their .apk. Note that when implementing this your clients
616- * must be able to deal with such files, either directly with
617- * {@link ContentResolver#openAssetFileDescriptor
618- * ContentResolver.openAssetFileDescriptor}, or by using the higher-level
668+ * inside of their .apk.
669+ * This method can be called from multiple threads, as described in
670+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
671+ * Processes and Threads</a>.
672+ *
673+ * <p>If you implement this, your clients must be able to deal with such
674+ * files, either directly with
675+ * {@link ContentResolver#openAssetFileDescriptor}, or by using the higher-level
619676 * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
620677 * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
621678 * methods.
622- *
623- * <p><em>Note: if you are implementing this to return a full file, you
679+ *
680+ * <p class="note">If you are implementing this to return a full file, you
624681 * should create the AssetFileDescriptor with
625682 * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
626- * applications that can not handle sub-sections of files.</em></ p>
683+ * applications that can not handle sub-sections of files.</p>
627684 *
628685 * @param uri The URI whose file is to be opened.
629686 * @param mode Access mode for the file. May be "r" for read-only access,
@@ -735,17 +792,20 @@ public void attachInfo(Context context, ProviderInfo info) {
735792 }
736793
737794 /**
738- * Applies each of the {@link ContentProviderOperation} objects and returns an array
739- * of their results. Passes through OperationApplicationException, which may be thrown
740- * by the call to {@link ContentProviderOperation#apply}.
741- * If all the applications succeed then a {@link ContentProviderResult} array with the
742- * same number of elements as the operations will be returned. It is implementation-specific
743- * how many, if any, operations will have been successfully applied if a call to
744- * apply results in a {@link OperationApplicationException}.
795+ * Override this to perform a batch of operations, or the default
796+ * implementation will {@link ContentProviderOperation#apply} each of the
797+ * {@link ContentProviderOperation} objects. If the apply calls all succeed
798+ * then a {@link ContentProviderResult} array with the same number of
799+ * elements as the operations will be returned. If any of the apply calls
800+ * fail, it is up to the implementation how many of the others take effect.
801+ * This method can be called from multiple threads, as described in
802+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
803+ * Processes and Threads</a>.
804+ *
745805 * @param operations the operations to apply
746806 * @return the results of the applications
747- * @throws OperationApplicationException thrown if an application fails.
748- * See {@link ContentProviderOperation#apply} for more information.
807+ * @throws OperationApplicationException thrown if any operation fails.
808+ * @see ContentProviderOperation#apply
749809 */
750810 public ContentProviderResult [] applyBatch (ArrayList <ContentProviderOperation > operations )
751811 throws OperationApplicationException {
0 commit comments