ContentProvider: An Android Paper for Learning Notes

Posted by Masterchief07 on Sat, 11 May 2019 14:25:38 +0200

ContentProvider is mainly used to realize data sharing between different applications. It provides a complete mechanism to allow one program to access data in another program, while ensuring the security of the visited data.

PS: The bottom layer of ContentProvider is to adopt the Binder mechanism in Android

The main methods of the ContentProvider class are:

<-- 4 Core Approaches -->
  public Uri insert(Uri uri, ContentValues values) 
  // External processes add data to ContentProvider

  public int delete(Uri uri, String selection, String[] selectionArgs) 
  // External processes delete data in ContentProvider

  public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
  // External processes update data in ContentProvider

  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,  String sortOrder)  
  // External application obtains data in ContentProvider



<-- 2 Three other ways -->
public boolean onCreate() 
// ContentProvider is called by the system when other processes first access the ContentProvider after it is created or after the system is opened.
// Note: The main thread running in the ContentProvider process cannot perform time-consuming operations.

public String getType(Uri uri)
// Get the data type, which is the MIME type that returns the data represented by the current Url

PS:
1) The four methods mentioned above are called back by the external process and run in the Binder thread pool of the ContentProvider process (not the main thread)
2) There are multithreaded concurrent access and thread synchronization is needed.
a. If ContentProvider's data storage method is using SQLite &1, it is not necessary, because the thread synchronization is well implemented within SQLite, and if there are multiple SQLites, it is necessary, because the thread synchronization between SQL objects is not possible.
b. If ContentProvider stores data in memory, it needs to synchronize threads by itself

3) Customized ContentProvider, rewriting six methods;

ContentResolver class

The ContentProvider class does not interact directly with external processes, but through the contentResolver class

Role: Unified management of different Content Provider operations, through URI can operate different content Provider data, external processes through the Content Resolver class to interact with the Content Provider class.

The ContentResolver class provides four methods with the same name and function as the ContentProvider class

/ External process orientation ContentProvider Add data to
public Uri insert(Uri uri, ContentValues values)  

// External processes delete data in ContentProvider
public int delete(Uri uri, String selection, String[] selectionArgs)

// External processes update data in ContentProvider
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)  

// External application obtains data in ContentProvider
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

UriMatcher class

Role; Register URIs in ContentProvider and match the corresponding tables in contentProvider according to URIs

// Step 1: Initialize the UriMatcher object
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//Constant UriMatcher.NO_MATCH = Return code that does not match any path
// Initialization does not match anything

// Step 2: Register URI (addURI ()) in ContentProvider
int URI_CODE_a = 1;
int URI_CODE_b = 2;
matcher.addURI("cn.scu.myprovider", "user1", URI_CODE_a);
matcher.addURI("cn.scu.myprovider", "user2", URI_CODE_b);
// If URI resource path = content://cn.scu.myprovider/user1, the registration code URI_CODE_a is returned.
// If URI resource path = content://cn.scu.myprovider/user2, the registration code URI_CODE_b is returned.

// Step 3: Match URI_CODE according to URI to match the corresponding resources in ContentProvider (match ())

@Override
public String getType (Uri uri){
    Uri uri = Uri.parse(" content://cn.scu.myprovider/user1");

    switch (matcher.match(uri)) {
        // The return code matched by URI is URI_CODE_a
        // That is matcher. match (uri) === URI_CODE_a
        case URI_CODE_a:
            return tableNameUser1;
        // If the return code matched by URI is URI_CODE_a, the table named tableNameUser1 in ContentProvider is returned.
        case URI_CODE_b:
            return tableNameUser2;
        // If the return code matched by URI is URI_CODE_b, the table named tableNameUser2 in ContentProvider is returned.
    }
}

ContentObserver class

Role: Observe Uri-induced data changes in contentProvider and notify the outside world.

// Step 1: Register ContentObserver for Content Observer
getContentResolver().registerContentObserver(uri);
// Register through the ContentResolver class and specify the URI to be observed

// Step 2: When the ContentProvider data of the URI changes, notify the outside world (that is, visitors accessing the ContentProvider data)
public class UserContentProvider extends ContentProvider {
    public Uri insert(Uri uri, ContentValues values) {
        db.insert("user", "userid", values);
        getContext().getContentResolver().notifyChange(uri, null);
        // Notify visitors
    }
}

// Step 3: Remove the observer
getContentResolver().unregisterContentObserver(uri);
// It also needs to be disassembled through the ContentResolver class

 

PS: Using ContentProvider mode, decoupling the storage mode of the underlying data, so that no matter what way the underlying data is stored, the external access mode to the data is uniform, which makes access simple and efficient.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Topics: SQLite Android SQL