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!