关于CotentProvider的跨进程调试
来源:互联网 发布:linux mysql 乱码 编辑:程序博客网 时间:2024/06/04 23:31
在我们日常工作中,有关上层应用与数据库交互的时候通常会用到ContentProvider这一组件。上层应用通过获得ContentResolver对象来调用其封装好的query、insert、delete、update等方法,这时通过跨进程通信会找到对应provider的相对应的query、insert等方法,在这里通过构建数据库对象来实现对SQLIte数据库的交互操作。
本文不会对ContentProvider的详细使用做过多的介绍,但是需要读者有一个大体的了解。应用代码与Provider代码都隶属于package层,不过前者在apps包下,后者在provider包下。
下面结合一个实际问题来分析一下如何跨进程追查代码:
DDMS的日志打印处显示出一个无效列名参数的异常,经排查发现是CallLogProvider中的query方法里传入的projection参数不正确,这时需要找到这个projection参数是如何传进来的。我们知道,上层应用通常并不是获取某个provider对象再调用其重写的query方法,而是通过ContentResolver对象,它们并不在同一个进程中,这样该如何找到时哪个进程调用了resolver的query方法进而将参数内容跨进程通信到provider的呢?
通过查看源代码不难发现,其实CallLogProvider中的query方法是通过ContentProvider的内部类Transport中的query方法调用的,具体代码如下:
public Cursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
enforceReadPermission(uri);
return ContentProvider.this.query(uri, projection, selection,
selectionArgs, sortOrder);
}
其中最后一句的ContentProvider.this.query就会根据java的多态机制找到CallLogProvider的query,而Transport里的query就是被ContentResolver调用的,代码如下:
public final Cursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
IContentProvider provider = acquireProvider(uri);
if (provider == null) {
return null;
}
try {
long startTime = SystemClock.uptimeMillis();
Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
……
}
首先会通过acquireProvider(uri)获得一个provider对象,其实是从ActivityThread下的acquireExistingProvider方法层层调用,它会根据uri找到在AndroidMenifest.xml文件中注册的provider,然后provider.query()就会进入指定的Provider的对应方法了。
因此,要先确定是哪个进程调用了CallLogProvider的query方法,可以在Transport的query方法中加入下面这两句:
long threadId = this.getCallingPid();
System.out.println(threadId);
这样我们就可以通过打印知道是哪个进程调用了这个query方法了,然后监听该进程和CallLogProvider所在的进程,在ContextWrapper类的getContentResolver()成员函数中添加断点,这样断电停下时,即可通过堆栈显示指导是哪调用了ContentResolver的query方法了,这样也就能判断它的参数是如何传进去的。
关于eclipse设置断点调试的时候,有时会遇到断点没有停下的问题,一般可能会有两点原因:一是打断点的位置并没有被执行,二是代码所在进程没有被监听。所以我们需要先打印出调用进程的id并对其监听,这样再打断点调试就会方便许多了。
- 关于CotentProvider的跨进程调试
- firefox调试记录4——关于跨进程的调试
- 关于Android 跨进程通信的文章?
- 关于跨进程的观察者模式
- 关于AIDL的跨进程通信
- 关于跨进程调用activity的问题
- 关于.net(C#)中的跨进程访问的问题
- 关于系统间数据一致性(跨进程事务)的解决方案
- 跨进程的CRITICAL_SECTION
- Bitmap 的跨进程
- 跨进程的双向通信
- 关于跨进程使用回调函数的研究:以跨进程获取Richedit中RTF流为例。
- 关于跨进程使用回调函数的研究:以跨进程获取Richedit中RTF流为例。
- 调试: 解决跨进程时使用CString报错的问题, [Invalid Address specified to RtlFreeHeap]
- 研究关于跨进程信息获取
- 关于Android跨进程通信整理
- 跨进程的SHOWMODAL效果
- 跨进程程序设计的模式
- WIP_ENTITIES.ENTITY_TYPE
- Twitter走在十字路口:从言论平台转向广告媒体引发争议
- jQuery Form Plugin:AJAX方式提交表单的完全方案
- java对象的序列化与反序列化(二)
- GSM CDMA WCDMA CDMA2000 TD-SCDMA
- 关于CotentProvider的跨进程调试
- dataset
- Ubuntu 11.04 安装 PostgreSQL 9.1
- 前段时间参加个访谈,题目……不让我修改,我是典型的穷人啊……以下是访谈稿
- 图形解锁的代码实现(付源码)
- resin服务器支持SSI相关配置
- Android网络编程
- WIP_DISCRETE_JOBS.WIP_SUPPLY_TYPE
- 一位软件工程师的6年总结