多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
本节将分析ContentProvider中另一个比较复杂的知识点,即query的实现。从ContentResolver的query函数开始,其代码如下: **ContentResolver.java::query** ~~~ /* 注意query中的参数,它们组合后得到的SQL语句如下(方括号中的语句为笔者添加的注释) SELECT projection指定的列名[如果projection为null,则使用“*”] FROM 表名[由目标CP根据uri参数设置] WHERE (selection)[如果selection中有通配符,具体参数由selectionArgs指定] ORDERYEDBY sortOrder */ public final Cursor query(Uri uri, String[]projection, String selection, String[] selectionArgs, String sortOrder) { /* 根据前面的分析,下面这个函数返回的provider的真实类型是ContentProviderProxy, 对应的Bn端对象的真实类型是ContentProvider的内部类Transport。本次执行query的 目标CP是MediaProvider */ IContentProvider provider = acquireProvider(uri); //来看下面的代码 try { long startTime = SystemClock.uptimeMillis(); //①调用远端进程的query函数 Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder); if (qCursor == null) { //如果返回的结果为空,则释放provider,这个函数的作用在7.2.3节介绍过 releaseProvider(provider); return null; } //②计算查询结果包含的数据项条数,结果保存在qCursor的内部变量中 qCursor.getCount(); long durationMillis = SystemClock.uptimeMillis() - startTime; //③最终返回给客户端一个游标对象,其真实数据类型为CursorWrapperInner return new CursorWrapperInner(qCursor, provider); } ~~~ 上面这段代码揭示了ContentResolver query函数的工作流程: - 调用远程CP的query函数,返回一个Cursor类型的对象qCursor。 - 该函数最终返给客户端的是一个CursorWrapperInner类型的对象。 Cursor和CursorWrappperInner这两个新出现的数据类型严重干扰了我们的思考。暂且不管它们,先来分析以上代码中列出的几个关键点函数。首先要分析的是第一个关键点函数query。