SQLite Database Learning Summary (2)

Source: Internet
Author: User
Tags connection pooling instance method sqlite database

3. SQLite's frameworks layer implements 3.1 frameworks layer architecture

The Android system is easy to use and encapsulates a content framework in the frameworks layer, which is called the content framework, not the database framework, because the contents are not necessarily from the database or from other data sources. Developers only need to know how to use Contentresovler and contentprovider to share data between application processes.

Here we only discuss the data source is the ContentProvider of the database, the developer needs to implement a Sqliteopenhelper derived class, it uses a series of SQLite related classes encapsulate the native layer of SQLite dynamic Library interface method, So how is sqlite encapsulated in the frameworks layer, what do we need to pay attention to when using SQLite?

Let's take a look at the overall architecture of the SQLite-based content framework:

Android system on frameworks layer

1, contentresolver:content framework of the client, to the application to provide add, delete, change, check the interface method, through the authority to specify the target content service, and connect to the server to perform data operations. 2, Contentprovider:content framework of the server, Android application of one of the four components, through the authority registered to the PMS, at run time when there is a client request by the AMS Dispatch to respond to the client's data operations. 3. Sqliteopenhelper: Manage SQLite's help class, providing a way to get an sqlitedatabase instance, which creates a sqlitedatabase instance when the first time the database is used, when the Get instance method is called. and dealing with database version changes, developers implement ContentProvider with a custom sqliteopenhelper class that handles the creation, upgrade, and demotion of data.    Note:

(1) Whether you call the Getwritabledatabase method or the Getreadabledatabase method, Sqliteopenhelper opens the database in read-write mode.

(2) If your application wants to open the database in Wal mode, you can call Setwriteaheadloggingenabled (true) in the constructor of your custom Sqliteopenhelper class.

    Sqliteopenhelper.java

    

4. Sqlitedatabase: Represents an open SQLite database that provides an interface method for performing database operations. If you do not need to share data between processes, your application can create instances of this class on its own to read and write to the SQLite database. 5, Sqlitesession:sqlitesession is responsible for managing the database connection and transaction life cycle, through Sqliteconnectionpool to obtain a database connection to perform specific database operations.

6. Sqliteconnectionpool: Database connection pool, manage all open database connections (Connection). All database connections are opened by it, joined to the connection pool when opened, and used to obtain a database connection from the connection pool when reading and writing the database.

7, Sqliteconnection: Represents the database connection, each connection encapsulates a native layer Sqlite3 instance, through the JNI call SQLite Dynamic Library interface method operation database, The connection is either held by the session or is held by the connection pool.

8. Cursorfactory: Optional cursor factory, you can provide a custom factory to create the cursor.

9, Databaseerrorhandler: Optional Database exception processor (currently processing only database corruption), if not provided, will use the default exception handler.

10, Sqlitedatabaseconfiguration: Database configuration, the application can create multiple connections to the SQLite database, this class is used to ensure that the configuration of each connection is the same.

11, Sqlitequery and Sqlitestatement: derived from abstract class Sqliteprogram, encapsulates the execution of SQL statements, and automatically assembles the SQL statements to be executed at execution time. and call Sqlitesession to perform the database operation. The implementation of these two classes applies the command pattern in design mode.  

3.2 Key Module implementations

This section describes the implementation of several key modules and the considerations that need to be taken into consideration when using them.

3.2.1 Sqlitesession

The database read and write operations on the frameworks layer of the Android system are done through sqlitesession, Sqlitesession is responsible for managing the database connection and the life cycle of the transaction.

A Sqlitedatabse instance can hold multiple active sessions at the same time (but to prevent deadlocks, each thread can hold only one DB session), each session gets the database connection when the SQL statement is executed, and releases the database connection after the SQL statement execution ends , the session maintains the database connection only during the execution of the SQL statement, and it is released when the execution is complete. This feature is also the basis for connection pooling.

Sqlitesession.java

If all connections in the connection pool have been allocated, the sqlitesession that gets the connection is blocked until a connection is available.

Therefore, the following points should be noted when using SQLite:

(1) Do not perform database operations in the UI thread.

(2) The execution of the transaction as short as possible.

(3) If the read and write transactions are long, consider using the Yieldtransaction () method to commit some of the transactions first, giving the opportunity to perform other transactions.

3.2.2 Sqliteconnectionpool

The database connection pool keeps all open database connections, and at any time a database connection is either held by a connection pool or held by a sqlitesession, and if Sqlitesession uses the database connection, it must be returned to the connection pool. If all connections in the connection pool are already in use, the pending transaction waits for an idle connection to be executed.

In the current implementation of the Android system, if the database is opened in a non-Wal mode, the connection pool will only maintain a database connection, if the database is opened in Wal mode, the maximum number of connections in the connection pool is determined by the system configuration, the default configuration is two.

Sqliteconnectionpool.java:

Although known as the connection pool, from the source view, the current implementation of the pool only a database connection (the future version of Android may be extended), so if there is a large number of concurrent database read and write operations in the application, the length of each operation may be affected, so the database operation should be placed in the worker thread execution To avoid affecting the UI response.

3.2.4 Cursor

The result of the data queried from the ContentProvider is returned to the client in the cursor, which appears to the client that the cursor is a data container, but the implementation that is hidden behind the cursor is flexible and its data can be returned not from the database. It can also be used in the real load, very good embodiment of object-oriented programming features and advantages.

In frameworks, the cursor is defined as an interface that is positioned as a data set that can be randomly accessed and defines a common method of accessing the dataset in the interface. Business can be based on their own needs to implement a cursor, how to implement the interface method is determined by the specific implementation, so the cursor has a lot of subclasses to meet the needs of different scenarios.

The sqlitecursor is returned through Sqlitedatabase, and if the data is not returned from the database, the developer can dynamically create a matrixcursor in ContentProvider and then populate the data and return it to the client.

From the cursor interface and the definition of its derived class, they do not implement the Parcelable interface, so how is it passed across the process? This requires the cursor to solve two problems first.

First question: Cursor does not implement the Parcelable interface, how does a cursor instance step into the call pass? The answer is not specific data, but binder references, which is to create a binder server instance of the cursor on the ContentProvider side, and then pass the binder application to the client, where the client obtains the queried data through this binder reference. Here frameworks defines an interface: Ibulkcursor.

Ibulkcursor defines the interface method that a cursor across a process needs to implement, where GetWindow () is used to get the data window, where OnMove () is used to move the cursor.

So the second one asks: we know that the size of the data passed by Binder is limited (1MB), and the size of the queried data may exceed the limit, so how do you pass data across processes? Since the data is variable in size, we will not pass the data through binder, but instead pass the data through shared memory, which is encapsulated in Cursorwindow.

Cursorwindow is the data window, which is allocated on the server (the window size is determined by the Android system configuration) and passed to the client, and the client is mapped to its own process space, so that the server-populated data can be read by the client. The GetWindow () method defined above in the Ibulkcursor interface is obtained Cursorwindow.

The Cursorwindow is empty at initialization, and when the cursor's Movetoxxx method is called, the cursor on the server is called through Ibulkcursor's OnMove () method to populate the contents of the Data window.

Cursorwindow.java

Frameworks\base\libs\androidfw\cursorwindow.cpp

Create shared memory on the server side.

Cursorwindow.java

Frameworks\base\libs\androidfw\cursorwindow.cpp

The client maps the shared memory to the process memory space.

The idea that frameworks solves the process of passing cursor data across processes Let's take a look at the specific classes that implement data passing across processes: Cursortobulkcursoradapter (server side) and Bulkcursortocursoradapter (client).

Service side:

Client:

In the Contentprovidernatvie class, you can see the cursor's special delivery process.

Service side:

Contentprovidernative.ontransact ()

Cursortobulkcursoradaptor.java

The server uses it to create a cursortobulkcursoradaptor instance after it gets the cursor through ContentProvider, The adaptor is then encapsulated in a Bulkcursordescriptor instance that implements the Parcelable interface and is returned to the client.

Although the data window is filled in when it is used, the cursor is actually passed through the code, and the server has already populated the data for the application once: Mcursor.getcount ().

Sqlitecursor.java

Client:

Contentproviderproxy.query ()

Bulkcursortocursoradaptor.java  

Creates a Bulkcursordescriptor instance after obtaining the data returned by the server, using it to initialize a Bulkcursortocursoradapter instance to return to the application.

SQLite Database Learning Summary (2)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.