VirtualApk源码分析

  • 时间:
  • 浏览:1
  • 来源:神彩排列三_彩神排列三官方

hook的IContentProvider对象

1、要能 所以人解析插件的结构的ContentProvider信息,就让 安装在去所以人线程池池结构呢?即安装在去ActivityThread的mProviderMap中。

ActivityThread.acquireProvider

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

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

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

wrapperUri

占坑的ContentProvider肯能有了,那么 接下来该为甚会 做呢?这里分为另一个方面:

肯能ContentProvider对应的线程池池那么 启动,就会调用startProcessLocked启动线程池池,创建线程池池就让通过Zygote创建,并运行线程池池的入口类ActivtyThread.main。startProcessLocked是异步的,所以无法立即选者线程池池不是启动完成。所以getContentProviderImpl函数中实现了如下代码来在等待ContentProvider所属的线程池池创建并完成ContentProvider的安装:

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

从前做那么 保证当前线程池池要能访问这一 ContentProvider,所以线程池池则无法访问,要外理ContentProvider的共享须要有经过AMS的getContentProvider过程,就让 要保证ProviderInfo在PMS肯能存在,这显然是不肯能的。

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

ContentImpl.getContentResolver

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

1、mProviderMap.getProviderByName(name, userId)查找当前不是肯能plublish,肯能那么 ,进入第2步

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

getContentProviderImpl在等待线程池池完成Provider的安装

2、代理转发,在宿主APP中拦截ContentProvider的操作,就让 将操作转给宿主占坑的ContentProvider,就让 再由占坑ContentProvider进行转发,调用插件中具体的ContentProvider对象。没错,VirtualApk就让那么 搞的。

android通过ContentProvider要能 实现线程池池间的数据共享,同类 APP通过MediaProvider要能 访问多媒体数据库的内容。通常大家 在Activity通过getContentResolver().query来跨线程池池访问数据库,ContentImpl.getContentResolver会返回ContentResolver对象,

那么 ContentProvider是那此时机安装的呢,答案就让ActivityThread.handleBindApplication:

IContentProviderProxy.invoke

RemoteContentProvider.query

线程池池创建后该运行Application,这里调用了installContentProviders完成ContentProvider的安装,注意安装ContentProvider存在在Application的onCreate过后 。

ApplicationContentResolver.acquireUnstableProvider调用了mMainThread.acquireProvider来获得IContentProvider,该对象要能 远程访问对方线程池池的ContentProvider,mMainThread就让当前线程池池的ActivityThread类。

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

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

ActivityThread.installContentProviders

ContentProvider安装完成后调用AMS.publishContentProvider,该操作将当前线程池池的ContentProvider保存到了AMS,从前有其余线程池池想访问这一 ContentProvider的过后 ,AMS就要能 直接返回,不须要再次安装了。

ContentResolver.query

mContentResolver的具体类型为ApplicationContentResolver,它继承自ContentResolver;在获取到ContentResolver通过其query措施要能 跨线程池池查询数据库,ContentResolver的query措施如下:

ActivityThread.handleBindApplication

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

acquireExistingProvider查询当前线程池池不是肯能保存过该ContentProvider的副本,副本的存在要能 提高多次访问同另一个ContentProvider的性能,肯能不存在副本,ActivityThread.acquireProvider就会调用AMS.getContentProvider函数来进行查找。查找过程如下:AMS.getContentProvider-->AMS.getContentProviderImpl。

acquireExistingProvider函数如下:

2、插件结构访问插件ContentProvider

acquireUnstableProvider

2、 调用AppGlobals.getPackageManager().resolveContentProvider()获取ProviderInfo,我觉得 就让调用PMS.resolveContentProvider,在APK安装的过后 ,PMS会解析AndroidManifest.xml文件。并将APK的ContentProvider信息保存成ProviderInfo。获取大屏ProviderInfo后进入第3步,

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

hookIContentProviderAsNeed完成hook工作:

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

hookIContentProviderAsNeeded

RemoteContentProvider.getContentProvider

1、插件结构访问插件ContentProvider

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

占坑的ContentProvider

getProcessRecordLocked

acquireExistingProvider

ApplicationContentResolver.acquireUnstableProvider