大家可以参考一下系统自带应用的代码,自定义了 signature 级别的 permission :
<permission android:name="com.android.gallery3d.filtershow.permission.READ" android:protectionLevel="signature" /> <permission android:name="com.android.gallery3d.filtershow.permission.WRITE" android:protectionLevel="signature" /> <provider android:name="com.android.gallery3d.filtershow.provider.SharedImageProvider" android:authorities="com.android.gallery3d.filtershow.provider.SharedImageProvider" android:grantUriPermissions="true" android:readPermission="com.android.gallery3d.filtershow.permission.READ" android:writePermission="com.android.gallery3d.filtershow.permission.WRITE" /> 1.11.1 如果我们只需要开放部份的 URI 给其他的应用访问呢?可以参考 Provider 的 URI 权限设置,只允许访问部份 URI ,可以参考原生 ContactsProvider2 的相关代码( 注意 path-permission 这个选项 ):
<provider android:name="ContactsProvider2" android:authorities="contacts;com.android.contacts" android:label="@string/provider_label" android:multiprocess="false" android:exported="true" android:grantUriPermissions="true" android:readPermission="android.permission.READ_CONTACTS" android:writePermission="android.permission.WRITE_CONTACTS"> <path-permission android:pathPrefix="/search_suggest_query" android:readPermission="android.permission.GLOBAL_SEARCH" /> <path-permission android:pathPrefix="/search_suggest_shortcut" android:readPermission="android.permission.GLOBAL_SEARCH" /> <path-permission android:pathPattern="/contacts/.*/photo" android:readPermission="android.permission.GLOBAL_SEARCH" /> <grant-uri-permission android:pathPattern=".*" /> </provider> 1.12 ContentProvider 接口方法运行在哪个线程中呢?ContentProvider 可以在 AndroidManifest.xml 中配置一个叫做 android:multiprocess 的属性,默认值是 false ,表示 ContentProvider 是单例的
无论哪个客户端应用的访问都将是同一个 ContentProvider 对象,如果设为 true ,系统会为每一个访问该 ContentProvider 的进程创建一个实例。
1.12.1 这点还是比较好理解的,那如果我要问每个 ContentProvider 的操作是在哪个线程中运行的呢?( 其实我们关心的是 UI 线程和工作线程 )比如我们在UI线程调用getContentResolver().query查询数据,而当数据量很大时(或者需要进行较长时间的计算)会不会阻塞UI线程呢?
要分两种情况回答这个问题:
ContentProvider 和调用者在同一个进程,ContentProvider 的方法( query/insert/update/delete 等 )和调用者在同一线程中;
ContentProvider 和调用者在不同的进程,ContentProvider 的方法会运行在它自身所在进程的一个 Binder 线程中。
但是,注意这两种方式在 ContentProvider 的方法没有执行完成前都会 blocked 调用者。所以你应该知道这个上面这个问题的答案了吧。
也可以看看 CursorLoader 这个类的源码,看 Google 自己是怎么使用 getContentResolver().query 的。
1.13 ContentProvider 是如何在不同应用程序之间传输数据的?一个应用进程有 16 个 Binder 线程去和远程服务进行交互,而每个线程可占用的缓存空间是 128KB 这样,超过会报异常。
ContentResolver 虽然是通过 Binder 进程间通信机制打通了应用程序之间共享数据的通道,但 ContentProvider 组件在不同应用程序之间传输数据是基于匿名共享内存机制来实现的。
有兴趣的可以查看一下老罗的文章Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划。
总结在这篇文章中,我对我所知道的 BroadcastReceiver 知识总进行了详细的总结,希望大家通过本次阅读都能有所收获。
重点:学 Android 有一段时间了,我打算好好的梳理一下所学知识,到现在为止,我才总结完 Activity 、Service 、BroadcastRecevier 等,有关 事件分发、滑动冲突、新能优化等重要模块,我后面也将详尽的总结,欢迎大家关注 _yuanhao 的 博客园 ,方便及时接收更新
如果有可以补充的知识点,欢迎大家在评论区指出。
码字不易,你的点赞是我总结的最大动力!由于我在「稀土掘金」「简书」「CSDN」「博客园」等站点,都有新内容发布。所以大家可以直接关注我的 GitHub 仓库,以免错过精彩内容!
仓库地址:
超级干货!精心归纳 Android 、JVM 、算法等,各位帅气的老铁支持一下!给个 Star !
一万多字长文,加上精美思维导图,记得点赞哦,欢迎关注 _yuanhao 的 博客园 ,我们下篇文章见!