[发明专利]一种Android系统无感知应用安装升级的方法有效

专利信息
申请号: 201810179483.4 申请日: 2018-03-05
公开(公告)号: CN108491216B 公开(公告)日: 2021-07-13
发明(设计)人: 王伟;和楠 申请(专利权)人: 北京指掌易科技有限公司
主分类号: G06F8/65 分类号: G06F8/65;G06F9/445
代理公司: 北京东方汇众知识产权代理事务所(普通合伙) 11296 代理人: 张淑贤
地址: 100085 北京市海淀区信*** 国省代码: 北京;11
权利要求书: 查看更多 说明书: 查看更多
摘要: 一种Android系统无感知应用安装升级的方法,包括如下步骤:先检测是否有新的升级包,若有,下载并保存新实体应用包到相关路径,之后升级;先调用宿主应用的attachBaseContext方法;再替换宿主ActivityThread中的所有的Application为实体应用的Application;下一步为替换资源;之后完善执行实体应用的Application的attach()方法以及执行相关的installContentProviders()方法;之后在执行宿主的onCreate()方法时反射执行实体的Application的onCreate()方法;替换完成。
搜索关键词: 一种 android 系统 感知 应用 安装 升级 方法
【主权项】:
1.一种Android系统无感知应用安装升级的方法,其特征在于,具体包括如下步骤:1)、打包创建宿主应用:1‑1)、给宿主应用定义;1‑2)、引用安卓系统的Application类;引用安卓系统的content.ComponentCallbacks类;引用安卓系统的content.Context类;引用安卓系统的content.pm.ApplicationInfo类;引用安卓系统的content.pm.PackageManager类;引用安卓系统的content.res.AssetManager类;引用安卓系统的content.res.Resources类;引用安卓系统的text.TextUtils类;1‑3)、引用宿主应用自定义的uusafe.shell.common.ZClassLoader类;引用宿主应用自定义的uusafe.shell.common.ZGlobal类;引用宿主应用自定义的uusafe.shell.common.ZLoader类;1‑4)、引用java语言的ref.WeakReference类;引用java语言的reflect.Field类;引用java语言的reflect.Method类;引用java提供的Collection类;引用java提供的HashMap类;引用java提供的Lis类;引用java提供的Map类;1‑5)、用自定义的ZApplication类去代替安卓应用默认的Application类;新定义mFieldAssets类,并进行初始化;新定义Object mAt类,并进行初始化;用自定义类的attachBaseContext()方法替换安卓应用默认的Application类中的attachBaseContext()方法,具体如下:自定义类加载器ZLoader类,new创建一个ZLoader的实例mLoader,mLoader检查是否有实体应用安装包real.apk,再使用ZClassLoader.patch方法将mLoader添加到宿主应用的类加载器的父亲位置(parent);再根据实体应用的真实的Application类名,调用java中反射的newInstance()方法获取实体应用的Application实例mImpl,再用java的反射方法拿到宿主应用的android.app.ActivityThread类的实例mAt,接着使用java的反射方法去替换mAt中所有的Application的对象实例,最后调用mImpl的attach函数从而来触发实体应用自己的Application(mImpl)的attachBaseContext()方法,来真正的开始执行实体应用相关的操作;宿主应用的入口是Application类,在宿主应用工程中创建一个继承系统Application的类ZApplication,用于在宿主应用刚启动时增加一个处理事件的时机,在宿主应用工程的清单文件(AndroidManifest.xml)中把所有的实体应用中的清单文件都拷贝过来,把实体应用的安装包real.apk放到宿主应用工程的assets文件夹中,安卓提供aapt命令打包编译资源文件生成R.java和resources.arsc,通过javac编译java文件生成class文件,通过dx来将java生成的class文件转化为安卓使用的dex文件,再使用aapt命令将之前生成的各种文件打包生成安卓安装包apk文件,同时安卓工程中的assets文件夹下面的文件原封不动的被aapt打入安装包,aapt最终生成包含实体应用的宿主安装包shell.apk,然后编译宿主应用工程打包生成宿主应用(shell.apk),将实体应用(real.apk)打入宿主应用安装包中,宿主应用运行时通过安卓系统提供的AssetManager.open(real.apk)方法来操作assets目录下的实体应用安装包文件;2)、安装宿主应用,宿主应用安装包包括清单文件(AndroidManifest)、assets文件夹、可执行文件(classes.dex)、资源文件(res),assets文件夹包括实体应用安装包,安装过程具体如下:安卓系统将安装包复制到/data/app/目录下,解压缩apk文件使用PackageManager来解析安装包的清单文件(AndroidManifest.xml)文件,获取应用注册的各种组件信息并缓存,然后执行dex优化过程将优化后的dex文件放入/data/dalvik_cache/文件夹下面,应用运行的时候直接执行此目录下优化好的dex文件;2a)、宿主应用的清单文件AndroidManifest.xml包含实体应用real.apk所有的清单文件,宿主应用的清单文件包括:实体应用清单文件声明的组件:活动Activity、广播BroadcastReceiver、服务Service、内容提供器ContentProvider和用于向安卓系统声明的该实体应用所需要的权限;宿主应用安装完成后,为了安全以及应用间隔离,安卓系统创建一个应用自己的私有目录“/data/data/om.suzhu.shell/”来存储运行时生成的文件和文件夹,如数据库文件,sharedprefence文件(android应用保存配置的文件)等,进入步骤2b);2b)、宿主应用启动时,安卓系统调用宿主应用的ZApplication类即初始化类的attachBaseContext()方法,安卓应用启动时候会触发调用attachBaseContext()方法,判断实体应用real.apk是否已经被放到/data/data/om.suzhu.shell/.uu/目录下:如果没有则调用安卓方法AssetManager.open(real.apk),将asset文件夹下面的实体应用real.apk放到宿主应用的运行目录/data/data/com.suzhu.shell(宿主应用包名)/.uu/中,用于宿主应用对其加载启动,之后,进入步骤3);如果实体应用real.apk已经被放到/data/data/om.suzhu.shell/.uu/目录下,则直接进入步骤3;3)、检测升级:进行联网,检测是否有新版本实体应用,若有新版本实体应用,进行联网更新,并将新版本实体应用的安装包下载到之前保存实体应用安装包的宿主应用的asset文件夹中,然后进入步骤3),如果没有新的实体应用安装包则直接进行步骤4);4)、实体应用dex字节码文件(可执行文件)优化:dex字节码文件(可执行文件)优化是个耗时过程,在宿主应用的清单文件中指定一个服务ZService继承于系统的Service,用于处理可执行文件的优化工作,为宿主应用正常执行,在宿主清单文件中为ZService服务指定一个单独的进程,此进程里的ZService服务里创建了一个自己的类加载器ZClassloader,继承于系统的ClassLoader,然后初始化ZClassLoader,利用ClassLoader初始化时优化传入路径apk文件的机制来实现实体应用dex字节码文件的优化,得到安卓设备能直接操作的机器码,优化完成后生成优化后的odex文件,即optimize‑dex文件,等宿主应用下一次启动的时候类加载器如果发现odex文件存在,则直接使用已经优化好的新版本实体应用的可执行文件;5)、实体应用启动:5a)、加载实体应用的类:安卓中类是通过类加载器ClassLoader加载的,创建ClassLoader的时候需要传入应用的dex文件路径、相应库路径,类加载器通过所述路径进行相关文件的处理,包括如在相关路径下加载类、优化dex路径下的dex文件,新创建一个类加载器ZClassLoader,并将类加载器ZClassLoader的参数dex文件路径、库路径相应赋值为实体应用的dex文件路径,如此在使用类加载器加载要使用的各种类的时候就会自动的去相关路径下寻找,具体执行过程是:判断宿主应用是否被启动,若否,继续等待,若是,宿主应用执行初始化方法attachBaseContext(),在宿主的attachBaseContext()方法中进行实体应用类加载器(classloader)的处理,详细过程如下:首先调用安卓系统提供的类的getClassLoader()方法得到宿主应用的类加载器OrgClassloader,再调用系统类加载器(classloader)提供的getParent()方法(OrgClassloader.getParent())得到原始类加载器OrgClassloader的父加载器ParentClassloader,创建在宿主的attachBaseContext()方法被系统触发调用的时候初始化自己的类加载器ZClassloader用于加载实体应用中使用到的各个类,ZClassloader继承于系统的Classloader类,构造函数:private ZClassLoader(ClassLoader orgParentClassLoader,String dexSearchPath,String libSearchPath,File cacheDir),传入参数包括宿主应用类加载器(orgClassLoader)的父类加载器(orgParentClassLoader)做为自己类加载器的父类加载器,传入实体应用安装包路径作为字节码文件的加载位置(dexSearchPath),传入使用到的库的路径(libSearchPath),最后一个参数是dex进行优化后存放的路径(cacheDir);根据类加载器的双亲委派机制,系统优先使用父一级的类加载器的原理,通过java反射调用的方式修改OrgClassloader的父类加载器为ZClassloader,拿到原始类加载器的父亲,再调用Field.set(OrgClassloader,ZClassLoader),将ZClassLoader设置为原始类加载器的父亲,保证类加载器ZClassLoader优先OrgClassloader使用,来达到加载实体应用类字节码的目的;5b)、应用配置信息替换:替换内存中已经生成的应用的全局的各种信息,包括应用全局配置里面的初始化类(Application)的实例、应用程序信息缓存(mInitialApplication)、所有应用进程信息缓存(mAllApplications)以及应用资源信息缓存(LoadedApk)对象、资源对应的LoadedApk里面的Application;宿主应用启动后安卓系统在内存中生成多种缓存数据,用于应用运行时使用,如果使用实体应用的各种应用信息则需要将这些内存中的数据都替换为实体应用的相应数据:通过前述生成的ZClassloader调用实体应用的可执行文件中的实现类,使用java的反射调用方式根据实体应用的Application类的名字创建实体应用的初始化类,即Application类;然后再利用java的反射机制(reflect机制)替换宿主应用的全局配置(即ActivityThread)中的所有的初始化类(Application)的实例为实体应用的初始化类(Application)的实例,所述替换是使用反射的方法直接修改相应对象实例里面的对应的域(field)的值,替换的内容包括:应用程序信息缓存(mInitialApplication)、所有应用进程信息缓存(mAllApplications)以及应用资源信息缓存(LoadedApk)对象和资源对应的LoadedApk里面的Application,一一替换,直到全部替换完;5c)、应用资源信息替换,宿主应用启动的时候安卓系统会将其安装包中的资源信息通过其原始的资源加载器(AssetManager)进行加载,每次运行的时候系统都会根据应用安装包的位置生成资源加载器AssetManager,并且通过LoadedApk,即资源与代码中引用的对应对象,将资源跟代码中引用的对应关系保存起来,LoadedApk对象是安卓安装包文件(apk)在内存中的表示,安卓系统在内存中创建LoadedApk的实例,并将资源信息和代码引用信息都保存在其中,之后,通过ContextImpl(即应用上下文环境)对象将应用资源信息保存起来,系统把生成的资源加载器对象保存到ContextImpl实例对象中的mResources对象中,通过各个Activity、ContentProvider、Service对象将此组件要使用的相关资源信息保存;生成新的资源加载器,通过java的反射方式将新的资源加载器替换到相关的LoadedApk、ContextImpl中,并生成应用各个组件需要的应用资源信息缓存,组件包括Activity、provider、service,当应用真正执行相关Activity活动、Service服务、ContentProvider内容提供者的初始化的时候进行对应的替换;详细的实现过程如下:在宿主应用的初始化方法即attachBaseContext被系统调用的时候,使用系统方法构造生成新的资源加载器即newAssetManager()实例,通过AssetManager中的添加方法即addAssetPath生成新的资源加载器实例,然后将此新的资源加载器替换到相应的应用运行时的环境中,首先是替换应用全局配置ActivityThread类实例中的mActiveResources对象中的各个Resources子对象对应的资源加载器,mActiveResources对象是包含Resources对象的集合,然后再替换ActivityThread实例中所有的LoadedApk对象中的mResources对象中的资源加载器mAssets,在ActivityThread中LoadedApk对象主要被系统保存在一个集合即mPackages对象中,通过java的反射机制取得这个集合即mPackages对象,然后再使用java的反射机制一一替换其中的资源加载器为实体应用的资源加载器,下一步替换应用上下文环境即Context实例中的mResources对象中的资源加载器(mAssets),宿主应用的Application对象也是实体应用要利用的上下文环境实例,Application类是继承于Context类,Application实例就是应用的上下文实例,java的反射机制反射宿主的Application对象拿到其中的mResources对象,再反射替换掉其中的资源加载器mAssets,最后再缓存应用的各个组件中使用的资源信息,即ResourceInfo、主题资源和文字资源等信息,即遍历实体应用的“活动”信息即ActivityInfo中各个“活动”即activity的资源信息,遍历各个服务的信息即ServiceInfo中的资源信息及各个内容提供者信息即ProviderInfo中的资源信息并保存在缓存中,当相应组件被使用的时候将此实体应用的资源信息提供给相应组件,各组件均是在ActivityThread类的消息队列中进行执行的,均通过mH的Handler对象进行,根据安卓Handler对象优先执行其中的mCallback的特性,通过java的反射机制替换此mCallback,然后当各组件初始化消息过来的时候根据之前保存的内存中的缓存来替换组件使用的ResourceInfo、主题资源和文字资源;5d)按照安卓系统正常启动应用的处理来执行此实体应用的启动过程:在点击图标启动正常应用的时候安卓桌面应用会先向系统的系统活动管理服务即ActivityManagerService简称AMS发送启动请求,AMS收到后会fork出一个新的进程作为此应用的进程,此新进程启动后创建消息事件处理队列,然后开始向AMS进行注册,以便应用跟AMS可以相互通信;经过前面的类加载器、资源等替换后,开始完善执行实体应用的Application的注册方法,向系统活动管理服务即ActivityManagerService注册,这个注册过程对应在ActivityThread类中的handleBindApplication()方法,是实体应用能否正常启动的关键一步,实现这个过程以便实体应用能正常启动,handleBindApplication()方法主要包含两个操作:实现安卓系统中Application类中的attach()方法执行的各个操作、执行相关的“内容提供器”的安装即installContentProviders()方法;通过类加载器生成实体应用的Application的实例,然后反射调用其attach()方法来完成attach()方法的处理,同样通过反射来调用ActivityThread中的installContentProviders方法来实现实体应用的installContentProviders方法,至此即完成整个应用的初始化即attachBaseContext()的处理,之后进入步骤6);6)、执行宿主的onCreate()方法,执行Application实例的onCreate()方法;通过java的反射机制对应调用执行实体的应用初始化类即Application)的onCreate()方法;7)、至此整个替换过程完成,可以至此使用动态加载的实体应用。
下载完整专利技术内容需要扣除积分,VIP会员可以免费下载。

该专利技术资料仅供研究查看技术是否侵权等信息,商用须获得专利权人授权。该专利全部权利属于北京指掌易科技有限公司,未经北京指掌易科技有限公司许可,擅自商用是侵权行为。如果您想购买此专利、获得商业授权和技术合作,请联系【客服

本文链接:http://www.vipzhuanli.com/patent/201810179483.4/,转载请声明来源钻瓜专利网。

×

专利文献下载

说明:

1、专利原文基于中国国家知识产权局专利说明书;

2、支持发明专利 、实用新型专利、外观设计专利(升级中);

3、专利数据每周两次同步更新,支持Adobe PDF格式;

4、内容包括专利技术的结构示意图流程工艺图技术构造图

5、已全新升级为极速版,下载速度显著提升!欢迎使用!

请您登陆后,进行下载,点击【登陆】 【注册】

关于我们 寻求报道 投稿须知 广告合作 版权声明 网站地图 友情链接 企业标识 联系我们

钻瓜专利网在线咨询

周一至周五 9:00-18:00

咨询在线客服咨询在线客服
tel code back_top