ContentProvider is one of the four components of Android and is implemented based on Binder mechanism in Android. It is mainly used for data transfer between processes.

Of course, all four components of Android can achieve inter-process communication, and the bottom layer is based on Binder to achieve.

Uniform Resource Identifier (URI)

Using a ContentProvider requires an introduction to uniform Resource identifiers (URIs).

Uris are divided into predefined and custom urIs, which respectively correspond to built-in system data (such as address book and calendar) and custom database

Take the following example of a URI for the content: / / com. Example. Myprovider/user:

Content: URI prefix.

Com.example. myProvider: unique identifier of the custom ContentProvider.

User: indicates a user-defined database table name.

Customize the ContentProvider within the application

Create a DBHeler class that inherits from SQLiteOpenHelper.

Use to create SqlLite database operation.

Public class DBHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME = "com_example_content_provider.db"; Public static final String USER_TABLE_NAME = "user"; Private static final int DATABASE_VERSION = 1; private static final int DATABASE_VERSION = 1; public DBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @override public void onCreate(SQLiteDatabase db) {db.execSQL("CREATE TABLE IF NOT EXISTS "+ USER_TABLE_NAME + "(_id INTEGER PRIMARY KEY AUTOINCREMENT," + " name TEXT)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }Copy the code

2. Create MyProvider that inherits from ContentProvider

It mainly implements the encapsulation of adding, deleting, changing and checking DB data.

public class MyProvider extends ContentProvider { public static final String TAG = "MyProvider_ContentProvider"; private Context mContext; DBHelper mDbHelper = null; SQLiteDatabase db = null; Public static final String AUTOHORITY = "com.example.myProvider "; public static final int User_Code = 1; // The UriMatcher class uses: Register urIs in the ContentProvider private static final UriMatcher mMatcher; Static {// initialize mMatcher = new UriMatcher(urimatcher.no_match); / / if the URI resource path = the content: / / com. Example. Myprovider/user, return the registration code User_Code mMatcher. AddURI (AUTOHORITY, "user", User_Code); } /** * Initialize the ContentProvider */ @override public Boolean onCreate() {mContext = getContext(); MDbHelper = new DBHelper(getContext()); mDbHelper = new DBHelper(getContext()); db = mDbHelper.getWritableDatabase(); Db.execsql ("delete from user"); db.execsql ("delete from user"); Db. ExecSQL ("insert into user values(1,' 1 ');" ); Db. ExecSQL ("insert into user values(2,' execs ');" ); Log.d(TAG,"onCreate"); return true; } /** * Add data */ @override public Uri insert(Uri Uri, ContentValues values) {// Match URI_CODE with Uri, String table = getTableName(URI); String table = getTableName(URI); Db. Insert (table, null, values); / / when the URI ContentProvider data changes, inform the outside world (i.e., access to the visitors to the ContentProvider data) mContext. GetContentResolver () notifyChange (URI, null); Log.d(TAG,"insert uri:"+uri); return uri; } /** ** ** / @override public Cursor query(Uri Uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {// Match the URI_CODE based on the URI, thus matching the corresponding table name in the ContentProvider String table = getTableName(URI); Log.d(TAG,"query uri:"+uri); Return db.query(table, projection, selection, selectionArgs, null, null, sortOrder, null); */ @override public int update(Uri Uri, ContentValues values, String selection, String selection) String[] selectionArgs) { Log.d(TAG,"update"); return 0; } /** * delete */ @override public int delete(Uri Uri, String selection, String[] selectionArgs) {log.d (TAG,"delete"); return 0; } @Override public String getType(Uri uri) { Log.d(TAG,"getType"); return null; */ private String getTableName(URI URI URI) {String tableName = null; switch (mMatcher.match(uri)) { case User_Code: tableName = DBHelper.USER_TABLE_NAME; break; } Log.d(TAG,"getTableName uri:"+uri); return tableName; }}Copy the code

The ContentProvider component needs to be declared in the manifest file:

<provider android:name=".contentprovider.MyProvider"
    android:authorities="com.example.myprovider"
/>
Copy the code

Create MyObserver from ContentObserver

Look at the code in the public Uri INSERT (Uri Uri, ContentValues values) method of MyProvider class above

/ / when the URI ContentProvider data changes, inform the outside world (i.e., access to the visitors to the ContentProvider data) mContext. GetContentResolver () notifyChange (URI, null);Copy the code

When MyObserver is called to insert data, the ContentProvider sends a notification to the outside world, which means that the ContentProvider can listen to the changes in the corresponding uri through the ContentObserver. When the URI data increases, MyObserver will print the current URI data in the MyObserver.

public class MyObserver extends ContentObserver{ public static final String TAG = "MyObserver_ContentProvider"; /** * Creates a content observer. * * @param handler The handler to run {@link #onChange} on, or null if none. */ public MyObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); / / set the URI URI uri_user = URI. Parse (" content: / / com. Example. Myprovider/user "); Resolver = myApplication.getContext ().getContentResolver(); Cursor = resolver.query(uri_user, new String[]{" id", "name"}, null, null, null); D (TAG,"query user:" + cursor.getint (0) + "" + cursor.getString(1)); } // Close the cursor at cursor.close(); }}Copy the code

4. Finally, the ContentProvider is called to print out the DB database data

Add a piece of data and print all the data for the database table corresponding to the current URI.

/ / set the URI URI uri_user = URI. Parse (" content: / / com. Example. Myprovider/user "); ContentValues values = new ContentValues(); values.put("_id", 3); Values. Put ("name", "wang wu "); // getContentResolver. ContentResolver = getContentResolver(); Insert (uri_user, values); // Insert data into the ContentProvider based on the URI of the ContentResolver. Cursor = resolver.query(uri_user, new String[]{" id", "name"}, null, null, null); D (TAG,"query user:" + cursor.getint (0) + "" + cursor.getString(1)); } // Close the cursor at cursor.close();Copy the code

Of course, we need to listen to getContentResolver().notifyChange(URI, null), so register MyObserver.

private MyObserver myObserver; // Register myObserver = new myObserver (new Handler()); getContentResolver().registerContentObserver(Uri.parse("content://com.example.myprovider/user"), false, myObserver); // Unbind if (myObserver! =null) { this.getContentResolver().unregisterContentObserver(myObserver); }Copy the code

That’s the basic use of ContentProvider. If you’re interested in listening to how ContentObserver is used, check out my post, # Two Ways to Boot Android Face the end of the navigation System of gestures in identifying a Settings. System. GetUriFor (” device_provisioned “) are introduced:

Portal: # Two ways for Android to boot from startup