框架层原理
从Provider使用方(Client App)通过getContentResolver()获取到Provider的远程对象,是一个三方的流程:
(1)Client App向AMS获取Provider远程对象;
(2)AMS会检查对应的Provider远程对象有没有发布到AMS,如果有,则直接返回给Client App;如果没有,则启动Provider App进程,并触发Provider App进程安装Provider;
(3)Provider App安装完成Provider之后,会调用AMS发布Provider远程对象到AMS;
(4)AMS将Provider对象返回给Client App。
以上过程中,对于Client App看起来,整个过程是同步的;在AMS中,获取Provider相关的方法都有同步锁,所以这个Provider远程对象实际上是同一个。下图说明这个过程:
Client App获取到Binder远程Provider对象之后,调用其数据操作方法,是在Provider App的Binder线程池中执行。
所以,在Provider层面,系统框架为App做到了Provider的单例,但没有做到Provider的线程安全。这需要在数据层面上自行实现。
对于数据库的场景,Android提供了SQLite。下面要看框架层对于SQLite的线程安全情况。
2.SQLiteDatabase/SQLiteOpenHelper线程安全
Android底层集成了SQLite数据库,在框架层,提供了一系列的API辅助访问SQLite数据库。这些类位于android.database.sqlite。
对于数据库,主要有两类操作涉及线程安全:第一、创建/升级/降级数据库;第二、数据的增删改查操作。
2.1 创建/升级/降级数据库
SQLiteOpenHelper是Android框架层提供给APP使用的打开SQLite数据库帮助API,常常和Provider捆绑使用。通过实现如下方法来实现数据库创建、升级、降级:
/**
* Called when the database is created for the first time. This is where the
* creation of tables and the initial population of the tables should happen.
*
* @param db The database.
*/
public abstract void onCreate(SQLiteDatabase db);
/**
* Called when the database needs