Before we talk about ContentProvider, let’s talk about SQLite and SQListeOpenHelper

SQL

SQLite

SQLite is a lightweight database, not a C/S structured database engine, but integrated into user applications. The library is also dynamically linked, and SQLite functionality is invoked directly from the API in the application, which is more efficient than cross-process communication. SQLite stores the entire database on the host as a single, cross-platform file

SQLite is the most widely deployed SQL database engine in the world. Database implementations in mobile operating systems such as Android and IOS use SQLite

Advantages:

  • No server, zero configuration, transactional.
  • A complete database stored in a single disk file
  • Database files can be freely shared between machines in different byte order
  • Supports 2TB database size
  • Small enough, full source code 250KB
  • Fast data manipulation
  • Open source

structure

1. The Interface (Interface)

The interface is made up of the SQLite C API, which means that programs, scripting languages, and library files ultimately interact with SQLite (ODBC/JDBC, which we usually use a lot, eventually translates into calls to the corresponding C API). 2. Compiler

In the compiler, tokenizers and parsers parse the SQL, convert it into a syntax tree, a hierarchical data structure that is more easily processed at the bottom, and pass the syntax tree to a code generator for processing. From it, the code generator generates assembly code for SQLite, which is executed by a Virtual Machine. 3. Virtual Machine

The most central part of the architecture is the Virtual machine, or Virtual Database Engine (VDBE). It is similar to the Java Virtual machine in that it interprets the execution of bytecode. The bytecode of VDBE consists of 128 opcodes, which are focused on database operations. Each of its instructions is used to perform specific database operations (such as opening a cursor for a table) or to prepare stack space for those operations (such as pushing in parameters). In summary, all of these instructions are intended to satisfy the requirements of SQL commands (more on VM later). 4. The back-end (the Back – End)

The back end consists of b-tree, page cache (Pager), and operating system interface (system call). B-tree and Page cache manage data together. The main function of B-tree is index, which maintains the complex relationship between each page, so as to quickly find the required data. The pager’s main role is to pass pages between b-Tree and Disk through the OS interface.

Reference:

SQLite profiling architecture

SQL Language Learning

Reference:

SQLite tutorial

SQListeOpenHelper

Is an SQLite helper action class

Common methods:

/** * create database */ / 1. Create or open database readable/write (by returning SQLiteDatabase object) getWritableDatabase () // 2. Create or open a readable database (via the returned SQLiteDatabase object) getReadableDatabase () // 3. The first time the database is created, // Overwrite onCreate(SQLiteDatabase db) // 4 in a subclass derived from SQLiteOpenHelper.  // Overwrite onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) // 5. Close () /** * Database operations (add, Delete, subtract, query) */ // 1. Query (String table, String[] columns, String Selection, String[] selectionArgs, String groupBy, String having, String orderBy, Stringlimit) // Querying the specified table returns a cursor set of data. // The parameters are described as follows: // table: table name // colums: array of column names // Selection: conditional clausewhere// groupBy: having group conditions // orderBy: sorting class //limit: paging query limits // Cursor: ResultSet (Cursor) rawQuery(String SQL, String[] selectionArgs) Return data set with cursor (biggest difference from above = prevent SQL injection) // 2. Delete (int) delete(String table,StringwhereClause,String[] whereThe Args) / / 3. Add data row (long) insert (String table, String nullColumnHack, ContentValues values) / / 4. Update (String table, ContentValues VALUES, StringwhereClause, String[] whereSQL > select * from String; // Select * from String;execSQL(String sql) 
Copy the code

reference

Android: SQLlite database user manual

ContentProvider

Definition: Content provider, one of the four components of Android

Function: To share data externally, the advantage of using ContentProvider is that the data access method is unified. In fact, it is a further encapsulation of SQListOpenHelper. It determines which database table to operate through Uri mapping

Uniform Resource Identifier (URI)

  • Schema: Fixed as content://
  • Authority: the only tag ContentProvider, the caller can find it through this
  • Path: database table to operate on
  • Id: an entry in a table
// Set URI URI = uri.parse ("content://com.carson.provider/User/1") // The URI refers to the resource: ContentProvider 'named' com.carson. Provider 'with id 1 in table' User '// Note that the URI pattern matches wildcards * & # // * : Match any length of a string of any valid characters / / the following the URI of the means to match any content provider the content: / / com. The example. The app. The provider / * / / # : Match the number of arbitrary length character string / / the following uris match the provider of the every row of the table table content: / / com. Example. App. The provider/table /# 
Copy the code

ContentResolver

The Uri is used to locate the ContentProvider registered with the system, and the ContentResolver is used to operate the corresponding database after the ContentProvider is found

Access: Context. GetContentResolver ()

Common methods: Insert, query, DELETE, update, etc

For example, read contacts

Custom ContentProvider

ContentProvider is actually a further encapsulation of SQLiteOpenHelper, using Uri mapping to determine which table in the database to operate, and to add, delete, and check changes.

Override insert, query, update, delete, getType methods


public class MyProvider extends ContentProvider {
	private SQLiteDatabase db;
	public static final String AUTOHORITY = "cn.scu.myprovider"; public static final int User_Code = 1; public static final int Job_Code = 2; private static final UriMatcher mUriMatcher; static { mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // initialize murimatcher. addURI(AUTOHORITY,"user",User_Code);
		mUriMatcher.addURI(AUTOHORITY,"job",Job_Code); If resource URI path = the content: / / / / cn. The scu. Myprovider/user, return the registration code if User_Code / / path = content: URI resources / / cn. Scu. Myprovider/job, Job_Code} /** * matches URI_CODE according to URI, To match the corresponding tableName in ContentProvider */ private String getTableName(Uri Uri){String tableName = null; switch (mUriMatcher.match(uri)) {case User_Code:
				tableName = MySQListOpenHelper.USER_TABLE_NAME;
				break;
			case Job_Code:
				tableName = MySQListOpenHelper.JOB_TABLE_NAME;
				break;
		}
		return tableName;
	}
	@Override
	public boolean onCreate() {// Initialize the database when ContentProvider is created // run on the main thread, SQLiteOpenHelper mDbHelper= new MySQListOpenHelper(getContext(),"test_person");
		db = mDbHelper.getWritableDatabase();
		return true;
	}

	@Nullable
	@Override
	public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
		returndb.query(getTableName(uri),projection,selection,selectionArgs,null,null,sortOrder,null); } @nullable @override public String getType(@nonnull Uri Uri) {// Return the MIME type of the data represented by the current Urlreturnnull; } @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { db.insert(getTableName(uri),null,values); // When the ContentProvider data of the URI changes, Notifying the outside world (i.e. visitors to the ContentProvider data) getContext().getContentResolver().notifyChange(URI, null);return uri;
	}

	@Override
	public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
		return 0;
	}

	@Override
	public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
		return0; }}Copy the code

UriMatcher

Function:

  • Register the URI in the ContentProvider
  • Match the corresponding data table in the ContentProvider based on the URI

ContentObserver

Definition: Content observer

Role: Watch Uri cause data changes in ContentProvider & notify outside world (i.e. visitors to the data)

// step 1: registerContentObserver ContentObserver getContentResolver().registercontentobserver (uri); // Register with the ContentResolver class and specify the URI to observe // Step 2: When the ContentProvider data for the URI changes, Public class UserContentProvider extends ContentProvider {public Uri insert(Uri Uri, ContentValues values) { db.insert("user"."userid", values); getContext().getContentResolver().notifyChange(uri, null); / / inform visitors}} / / step 3: remove the observer getContentResolver () unregisterContentObserver (uri). // This is also done using the ContentResolver classCopy the code

Synchronization issues

The ContentProvider uses SQList as a data store and does not need to worry about thread synchronization because SQList implements thread synchronization internally

Storage is another way to worry about thread synchronization

Reference:

Android development steps from the handyman to the expert

Android: All about ContentProvider knowledge here!