B:URI 的标识,用于唯一标识这个 ContentProvider ,外部调用者可以根据这个标识来找到它。它定义了是哪个 ContentProvider 提供这些数据。对于第三方应用程序,为了保证 URI 标识的唯一性,它必须是一个完整的、小写的类名。这个标识在元素的 authorities 属性中说明:一般是定义该 ContentProvider 的包类的名称;
C:路径( path ),通俗的讲就是你要操作的数据库中表的名字,或者你也可以自己定义,记得在使用的时候保持一致就可以了;"content://com.bing.provider.myprovider/tablename"。
D:如果URI中包含表示需要获取的记录的 ID;则就返回该id对应的数据,如果没有 ID,就表示返回全部; "content://com.bing.provider.myprovider/tablename/#" # 表示数据 id 。
1.7 如何访问 asserts 资源目录下的数据库?把数据库 db 复制到 /data/data/packagename/databases/ 目录下, 然后直接就能访问了。
1.8 多个进程同时调用一个 ContentProvider 的 query 获取数据,ContentPrvoider 是如何反应的呢?一个 ContentProvider 可以接受来自另外一个进程的数据请求。
尽管 ContentResolver 与 ContentProvider 类隐藏了实现细节,但是 ContentProvider 所提供的 query(),insert(),delete(),update() 都是在 ContentProvider 进程的线程池中被调用执行的,而不是进程的主线程中。
这个线程池是有 Binder 创建和维护的,其实使用的就是每个应用进程中的 Binder 线程池。
1.9 Android 设计 ContentProvider 的目的是什么呢?隐藏数据的实现方式,对外提供统一的数据访问接口;
更好的数据访问权限管理。ContentProvider 可以对开发的数据进行权限设置,不同的 URI 可以对应不同的权限,只有符合权限要求的组件才能访问到 ContentProvider 的具体操作。
ContentProvider 封装了跨进程共享的逻辑,我们只需要 Uri 即可访问数据。由系统来管理 ContentProvider 的创建、生命周期及访问的线程分配,简化我们在应用间共享数据( 进程间通信 )的方式。我们只管通过 ContentResolver 访问 ContentProvider 所提示的数据接口,而不需要担心它所在进程是启动还是未启动。
1.10 运行在主线程的 ContentProvider 为什么不会影响主线程的UI操作?ContentProvider 的 onCreate() 是运行在 UI 线程的,而 query() ,insert() ,delete() ,update() 是运行在线程池中的工作线程的
所以调用这向个方法并不会阻塞 ContentProvider 所在进程的主线程,但可能会阻塞调用者所在的进程的 UI 线程!
所以,调用 ContentProvider 的操作仍然要放在子线程中去做。
虽然直接的 CRUD 的操作是在工作线程的,但系统会让你的调用线程等待这个异步的操作完成,你才可以继续线程之前的工作。
1.11 外提供数据共享,那么如何限制对方的使用呢?android:exported 属性非常重要。这个属性用于指示该服务是否能够被其他应用程序组件调用或跟它交互。
如果设置为 true,则能够被调用或交互,否则不能。
设置为 false 时,只有同一个应用程序的组件或带有相同用户 ID 的应用程序才能启动或绑定该服务。
对于需要开放的组件应设置合理的权限,如果只需要对同一个签名的其它应用开放 ContentProvider ,则可以设置 signature 级别的权限。