Content Provider之间互相通信的源码浅析

写在前面:本文是根据大神的博客http://blog.csdn.net/luoshengyang/article/details/6967204,对android5.0系统进行了分析

一、个人理解

分析之前先说一下,自己对Content Provider进程间通信的基本理解。个人认为,Android中进程间通信的套路都是基本一致。基本和AIDL差不多。其实AIDL本身就是用来在进程之间通信的。这里先说一下进程间通信的大体套路。假设client进程要向server进程传递数据或访问数据,首先,两个进程要拥有相同的接口(假设为A),因为我们我们要使他们的对象相同,做到面向对象编程,即调用client进程的A对象,就像调用server进程的A对象一样。第二,进程间的通信是用代理模式来实现的,所以在server进程要有一个真正用于提供服务的类AA(实现了A),在client进程会有一个AProxy类,用来代表AA,这样我们在client做的操作就可以有Aproxy传到server的AA中了。第三,既然是进程间通信,那么Binder也是必不可少的。它会将在client端所做的操作传递到server端。这里我们附一张图来说明一下:现在我们以content provider,来看一下进程间通信的实现机制:

好了,回到正题,说一下content provider的通信。它的通信和进程间的通信是基本一致的,但是,它也有些不同,在Content Provider的通信中会有一个CursorWindow类,它的作用是用来储存查询到的数据,client端和server端会共享这个CursorWindow类型的对象,从而实现数据的交流。

二、content provider通信分析

1、client端provider的获得

在上一节我们说过content provider的启动。content provider启动的最后阶段,会调用AMS的getContentProvider()方法来返回一个ContentProviderHolder型的holder对象,它里面包含了已经加载好的provider对象,但是这里的provider对象并不是真正的服务端的provider对象,而是一个ContentProviderProxy对象,它里面包含了用于进程间通信的binder。下面让我们来看一下这个ContentProviderProxy对象是如何获得的:

1.1获得holder:

 holder = ActivityManagerNative.getDefault().getContentProvider(
                    getApplicationThread(), auth, userId, stable);
从上段代码可以看出,holder是通过一个AMS来获得的,而这个AMS对象其实也不是真正的AMS,它只是AMS位于client端的代理对象(因为AMS在系统进程中运行),它的类型为ActivityManagerProxy。知道AMS后,我们在看一下它是如何获得holder的

1.2ActivityManagerProxy的getContentProvider()

 public ContentProviderHolder getContentProvider(IApplicationThread caller,
            String name, int userId, boolean stable) throws RemoteException {
        ......
        mRemote.transact(GET_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
        ......
        ContentProviderHolder cph = null;
        if (res != 0) {
            cph = ContentProviderHolder.CREATOR.createFromParcel(reply);
        }
        data.recycle();
        reply.recycle();
        return cph;
    }

1.3这里的mBinder是AMS进程发过来的binder对象,用来和真正的AMS通信,从上面的代码可以看出,它会向真正的AMS请求provider对象,具体实现如下:

case GET_CONTENT_PROVIDER_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            ......
            ContentProviderHolder cph = getContentProvider(app, name, userId, stable);
            reply.writeNoException();
            if (cph != null) {
                reply.writeInt(1);
                cph.writeToParcel(reply, 0);
            } else {
  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值