VirtualApk源码分析

  • 时间:
  • 浏览:3

hook的IContentProvider对象

原本做并能保证当前任务管理器池池并能访问这种ContentProvider,许任务管理器池池池则无法访问,要处里ContentProvider的共享还要有经过AMS的getContentProvider过程,如果 要保证ProviderInfo在PMS肯能所处,这显然是不肯能的。

hookIContentProviderAsNeeded替换了ActivityThread中肯能安装好的auth对应的IContentProvider,改用我本人的IContentProviderProxy。

ApplicationContentResolver.acquireUnstableProvider

插件结构访问插件ContentProvider,首先还要调用PluginContentResolver.wrapperUri将对插件访问的URI转为content://host_authority/plugin_authority格式,如果 再由占坑ContentProvider进行转发。

ActivityThread.installContentProviders

android通过ContentProvider后能 实现任务管理器池池间的数据共享,相似APP通过MediaProvider后能 访问多媒体数据库的内容。通常亲戚当我们都都 在Activity通过getContentResolver().query来跨任务管理器池池访问数据库,ContentImpl.getContentResolver会返回ContentResolver对象,

占坑的ContentProvider肯能有了,没办法 接下来该为什么会么会做呢?这里分为一一兩个多多方面:

2、 调用AppGlobals.getPackageManager().resolveContentProvider()获取ProviderInfo,确实 只是调用PMS.resolveContentProvider,在APK安装的如果 ,PMS会解析AndroidManifest.xml文件。并将APK的ContentProvider信息保存成ProviderInfo。获取大屏ProviderInfo后进入第3步,

RemoteContentProvider.query

肯能ContentProvider对应的任务管理器池池没办法 启动,就会调用startProcessLocked启动任务管理器池池,创建任务管理器池池只是通过Zygote创建,并运行任务管理器池池的入口类ActivtyThread.main。startProcessLocked是异步的,许多无法立即选泽任务管理器池池是是是否是是启动完成。许多getContentProviderImpl函数中实现了如下代码来等待图片ContentProvider所属的任务管理器池池创建并完成ContentProvider的安装:

1、后能 我本人解析插件的结构的ContentProvider信息,如果 安里装我本人任务管理器池池结构呢?即安里装ActivityThread的mProviderMap中。

3、创建ContentProviderRecord对象,通过getProcessRecordLocked获取ContentProviderRecord对应的任务管理器池池是是是否是是启动,肯能任务管理器池池肯能启动,就将ContentProviderRecord保存到ContentProvider所属任务管理器池池的pubProviders中,并调用AppliationThread.scheduleInstallProvider(会调用ActivityThread.installContentProviders)进行ContentProvider的安装。

任务管理器池池创建时会运行Application,这里调用了installContentProviders完成ContentProvider的安装,注意安装ContentProvider所处在Application的onCreate如果 。

IContentProviderProxy.invoke

hookIContentProviderAsNeed完成hook工作:

mContext.getContentResolver().call(uri,"wakeup",null,null);十分重要,uri="content://packageName.VirtualAPK.Provider",他完成了RemoteContentProvider的安装,原本在ActivityThread中就保存了RemoteContentProvider对应的IContentProvider对象,如果 给这种对象设置代理即可。原本当当前任务管理器池池再访问RemoteContentProvider时就直接使用这种代理。

ContentResolver.query

在了解了ContentProvider的运行流程后,要怎样对其进行插件化呢?这里有如下思路:

acquireExistingProvider函数如下:

首先获取了unstableProvider对象,获取经过:ContentResolver.acquireUnstableProvider-->ApplicationContentResolver.acquireUnstableProvider

getContentProvider通过反射创建出插件ContentProvider对象,最后调用ContentProvider.query完成查询。

acquireExistingProvider查询当前任务管理器池池是是是否是是肯能保存过该ContentProvider的副本,副本的所处后能 提高多次访问同一一兩个多多ContentProvider的性能,肯能不所处副本,ActivityThread.acquireProvider就会调用AMS.getContentProvider函数来进行查找。查找过程如下:AMS.getContentProvider-->AMS.getContentProviderImpl。

getContentProviderImpl等待图片任务管理器池池完成Provider的安装

占坑的ContentProvider

ActivityThread.acquireProvider

getProcessRecordLocked

1、插件结构访问插件ContentProvider

mPluginManager.resolveContentProvider判断是是是否是是是查询插件的ContentProvider,肯能是就使用Hook过对象:

ActivityThread.handleBindApplication

2、插件结构访问插件ContentProvider

原本就插件结构在获取插件ContentProvider时的请求就转到了宿主ContentProvider中。

没办法 ContentProvider是哪此时机安装的呢,答案只是ActivityThread.handleBindApplication:

ApplicationContentResolver.acquireUnstableProvider调用了mMainThread.acquireProvider来获得IContentProvider,该对象后能 远程访问对方任务管理器池池的ContentProvider,mMainThread只是当前任务管理器池池的ActivityThread类。

ContentImpl.getContentResolver

2、代理转发,在宿主APP中拦截ContentProvider的操作,如果 将操作转给宿主占坑的ContentProvider,如果 再由占坑ContentProvider进行转发,调用插件中具体的ContentProvider对象。没错,VirtualApk只是没办法 搞的。

插件结构使用的Context是PluginContext,VirtualApk复写了getContentResolver函数,返回了我本人实现的PluginContentResolver。PluginContentResolver结构重写了acquireProvider、acquireExistingProvider、acquireUnstableProvider函数,这里以acquireUnstableProvider为例:

invoke函数首先将访问插件的Uri转到宿主占坑Uri:

acquireUnstableProvider

mContentResolver的具体类型为ApplicationContentResolver,它继承自ContentResolver;在获取到ContentResolver通过其query方式后能 跨任务管理器池池查询数据库,ContentResolver的query方式如下:

ContentProvider安装完成后调用AMS.publishContentProvider,该操作将当前任务管理器池池的ContentProvider保存到了AMS,原本有其余任务管理器池池想访问这种ContentProvider的如果 ,AMS就后能 直接返回,不还要再次安装了。

RemoteContentProvider.getContentProvider

hookIContentProviderAsNeeded

1、mProviderMap.getProviderByName(name, userId)查找当前是是是否是是肯能plublish,肯能没办法 ,进入第2步

在完成URI转换后,所有请求都转给了宿主占坑ContentProvider,下面就还要进行代理转发:

wrapperUri

Uri的个数变成了content://host_authority/plugin_authority,其中host_authority表示宿主占坑ContentProvider对应的Auth,plugin_authority代表了实际要启动的插件ContentProvider的许多信息。

acquireExistingProvider