Skip to content

Commit 86c035f

Browse files
bradfitzAndroid (Google) Code Review
authored andcommitted
Merge "COMMENT ONLY change to clarify ContentProvider documentation." into froyo
2 parents 8c65ee2 + 6fcc0f0 commit 86c035f

File tree

2 files changed

+148
-69
lines changed

2 files changed

+148
-69
lines changed

core/java/android/content/ContentProvider.java

Lines changed: 119 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,23 @@
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
*/
7078
public 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 {

core/java/android/database/sqlite/SQLiteOpenHelper.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,16 @@
2222

2323
/**
2424
* A helper class to manage database creation and version management.
25-
* You create a subclass implementing {@link #onCreate}, {@link #onUpgrade} and
25+
*
26+
* <p>You create a subclass implementing {@link #onCreate}, {@link #onUpgrade} and
2627
* optionally {@link #onOpen}, and this class takes care of opening the database
2728
* if it exists, creating it if it does not, and upgrading it as necessary.
2829
* Transactions are used to make sure the database is always in a sensible state.
30+
*
31+
* <p>This class makes it easy for {@link android.content.ContentProvider}
32+
* implementations to defer opening and upgrading the database until first use,
33+
* to avoid blocking application startup with long-running database upgrades.
34+
*
2935
* <p>For an example, see the NotePadProvider class in the NotePad sample application,
3036
* in the <em>samples/</em> directory of the SDK.</p>
3137
*/
@@ -42,8 +48,9 @@ public abstract class SQLiteOpenHelper {
4248

4349
/**
4450
* Create a helper object to create, open, and/or manage a database.
45-
* The database is not actually created or opened until one of
46-
* {@link #getWritableDatabase} or {@link #getReadableDatabase} is called.
51+
* This method always returns very quickly. The database is not actually
52+
* created or opened until one of {@link #getWritableDatabase} or
53+
* {@link #getReadableDatabase} is called.
4754
*
4855
* @param context to use to open or create the database
4956
* @param name of the database file, or null for an in-memory database
@@ -62,13 +69,20 @@ public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int
6269

6370
/**
6471
* Create and/or open a database that will be used for reading and writing.
65-
* Once opened successfully, the database is cached, so you can call this
66-
* method every time you need to write to the database. Make sure to call
67-
* {@link #close} when you no longer need it.
72+
* The first time this is called, the database will be opened and
73+
* {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be
74+
* called.
6875
*
69-
* <p>Errors such as bad permissions or a full disk may cause this operation
76+
* <p>Once opened successfully, the database is cached, so you can
77+
* call this method every time you need to write to the database.
78+
* (Make sure to call {@link #close} when you no longer need the database.)
79+
* Errors such as bad permissions or a full disk may cause this method
7080
* to fail, but future attempts may succeed if the problem is fixed.</p>
7181
*
82+
* <p class="caution">Database upgrade may take a long time, you
83+
* should not call this method from the application main thread, including
84+
* from {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
85+
*
7286
* @throws SQLiteException if the database cannot be opened for writing
7387
* @return a read/write database object valid until {@link #close} is called
7488
*/
@@ -141,6 +155,11 @@ public synchronized SQLiteDatabase getWritableDatabase() {
141155
* database object will be closed and the read/write object will be returned
142156
* in the future.
143157
*
158+
* <p class="caution">Like {@link #getWritableDatabase}, this method may
159+
* take a long time to return, so you should not call it from the
160+
* application main thread, including from
161+
* {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
162+
*
144163
* @throws SQLiteException if the database cannot be opened
145164
* @return a database object valid until {@link #getWritableDatabase}
146165
* or {@link #close} is called.
@@ -219,9 +238,9 @@ public synchronized void close() {
219238
public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
220239

221240
/**
222-
* Called when the database has been opened.
223-
* Override method should check {@link SQLiteDatabase#isReadOnly} before
224-
* updating the database.
241+
* Called when the database has been opened. The implementation
242+
* should check {@link SQLiteDatabase#isReadOnly} before updating the
243+
* database.
225244
*
226245
* @param db The database.
227246
*/

0 commit comments

Comments
 (0)