[Android5.1]ContentProvider的Binder通信分析

来源:互联网 发布:video.js flash 编辑:程序博客网 时间:2024/05/23 01:25

这篇文章大体介绍一下ContentProvider提供方和使用方之间如何通过binder机制进行通信的。
下面是ContentProvider相关的类图关系:

这里写图片描述

IContentProvider

ContentProvider接口类,继承于IInterface类。该类有两个很重要的子类:ContentProviderNative和ContentProviderProxy,分别为本地服务端和客户端的接口。

ContentProviderProxy

PATH:frameworks/base/core/java/android/content/ContentProviderNative.java
为Content客户端接口。Content使用方获得该接口后,就可以调用接口里的query/insert/delete/update函数进行内容的查询、插入、删除和更新。里面有个IBinder类型的变量mRemote,使用mRemote的transact方法就可以将具体的请求发给binder驱动,binder驱动会进一步将该请求转发给Content提供方。下面以ContentProviderProxy.query为例,看一下具体实现:

public Cursor query(String callingPkg, Uri url, String[] projection, String selection, String[] selectionArgs,       String sortOrder, ICancellationSignal cancellationSignal) throws RemoteException {        Parcel data = Parcel.obtain();    Parcel reply = Parcel.obtain();    try {        // 将请求打包到Parceldata.writeInterfaceToken(IContentProvider.descriptor);        data.writeString(callingPkg);              data.writeInt(length);        ...        // 将请求包发送给binder驱动。注意这里的请求类型为:IContentProvider.QUERY_TRANSACTION        mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);           // 将返回结果转化为Cursor类型        if (reply.readInt() != 0) {            BulkCursorDescriptor d = BulkCursorDescriptor.CREATOR.createFromParcel(reply);            adaptor.initialize(d);        } else {            adaptor.close();            adaptor = null;        }        return adaptor; //返回结果    } }

ContentProviderNative

PATH:frameworks/base/core/java/android/content/ContentProviderNative.java
为Content本地服务端接口,里面有个方法为onTransact,该方法主要是处理来自Content客户端的请求,然后调用其子类Transport来具体实现query/insert/delete/update等具体的操作。下面看一下具体代码:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {    try {        switch (code) {            case QUERY_TRANSACTION:            {                ... //解析请求包data                // 调用子类的query具体实现,即ContentProvider.Transport类。                Cursor cursor = query(callingPkg, url, projection, selection, selectionArgs,                        sortOrder, cancellationSignal);                ... //将处理结果放入返回包reply中                return true;            }            case GET_TYPE_TRANSACTION:  //getType操作            {                ...            }            case INSERT_TRANSACTION:   //insert操作            {                ...            }            case DELETE_TRANSACTION:   //delete操作            {                ...            }            case UPDATE_TRANSACTION:   //update操作            {                ...            }            ...        }    }     ...}

ContentProvider

PATH:frameworks/base/core/java/android/content/ContentProvider.java
该类是一个抽象类,所有的Provider都继承于该类。ContentProvider定义了query/insert/delete/update的接口形式,具体实现由其子类完成。

public abstract class ContentProvider implements ComponentCallbacks2 {    public abstract Cursor query(Uri uri, String[] projection,            String selection, String[] selectionArgs, String sortOrder);    public abstract Uri insert(Uri uri, ContentValues values);    public abstract int delete(Uri uri, String selection, String[] selectionArgs);    public abstract int update(Uri uri, ContentValues values, String selection, String[] selectionArgs);    ...}

ContentProvider中还有一个内部类:Transport,其继承于ContentProviderNative,该类里面实现了query/insert/delete/update方法,由ContentProviderNative.onTransact调用。但这些方法仍然不是最终的实现,还需要进一步调用具体的ContentProvider实现。
下面以Transport.query()为例,看一下具体代码:

class Transport extends ContentProviderNative {    public Cursor query(String callingPkg, Uri uri, String[] projection,            String selection, String[] selectionArgs, String sortOrder,            ICancellationSignal cancellationSignal) {        ...        try {            // 由于ContentProvider是抽象类,因此进一步调用ContentProvider的子类的query方法。            return ContentProvider.this.query(                    uri, projection, selection, selectionArgs, sortOrder,                    CancellationSignal.fromTransport(cancellationSignal));        } finally {            setCallingPackage(original);        }    }    ...}

XXXProvider

这里就是系统中某一个ContentProvider的具体实现了,比如MediaProvider、SettingsProvider等。
这些类继承于ContentProvider类,因此必须要实现ContentProvider类中定义的query/insert/delete/update抽象方法。

0 0
原创粉丝点击