CN108491216A - 一种Android系统无感知应用安装升级的方法 - Google Patents
一种Android系统无感知应用安装升级的方法 Download PDFInfo
- Publication number
- CN108491216A CN108491216A CN201810179483.4A CN201810179483A CN108491216A CN 108491216 A CN108491216 A CN 108491216A CN 201810179483 A CN201810179483 A CN 201810179483A CN 108491216 A CN108491216 A CN 108491216A
- Authority
- CN
- China
- Prior art keywords
- application
- host
- classes
- entity
- classloader
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
- 238000000034 method Methods 0.000 title claims abstract description 164
- 238000009434 installation Methods 0.000 title claims abstract description 80
- 230000008569 process Effects 0.000 claims description 46
- 230000000694 effects Effects 0.000 claims description 33
- 230000007246 mechanism Effects 0.000 claims description 29
- 238000005457 optimization Methods 0.000 claims description 23
- 230000015654 memory Effects 0.000 claims description 19
- 238000012545 processing Methods 0.000 claims description 19
- 230000011514 reflex Effects 0.000 claims description 16
- 230000006870 function Effects 0.000 claims description 5
- 238000004321 preservation Methods 0.000 claims description 5
- 230000008859 change Effects 0.000 claims description 4
- 230000007613 environmental effect Effects 0.000 claims description 4
- 238000001028 reflection method Methods 0.000 claims description 4
- 210000003626 afferent pathway Anatomy 0.000 claims description 3
- 238000013459 approach Methods 0.000 claims description 3
- 230000000712 assembly Effects 0.000 claims description 3
- 238000000429 assembly Methods 0.000 claims description 3
- 238000004891 communication Methods 0.000 claims description 3
- 238000010276 construction Methods 0.000 claims description 3
- 230000006837 decompression Effects 0.000 claims description 3
- 238000001514 detection method Methods 0.000 claims description 3
- 230000000977 initiatory effect Effects 0.000 claims description 3
- 230000006855 networking Effects 0.000 claims description 3
- 230000006399 behavior Effects 0.000 claims description 2
- 238000004064 recycling Methods 0.000 claims description 2
- 238000011900 installation process Methods 0.000 claims 1
- 238000013461 design Methods 0.000 description 9
- 230000008439 repair process Effects 0.000 description 4
- 238000010586 diagram Methods 0.000 description 3
- 238000009432 framing Methods 0.000 description 2
- 238000011084 recovery Methods 0.000 description 2
- 230000006978 adaptation Effects 0.000 description 1
- 238000003491 array Methods 0.000 description 1
- 230000008901 benefit Effects 0.000 description 1
- 235000013399 edible fruits Nutrition 0.000 description 1
- 238000005516 engineering process Methods 0.000 description 1
- 238000007689 inspection Methods 0.000 description 1
- 230000004048 modification Effects 0.000 description 1
- 238000012986 modification Methods 0.000 description 1
- 238000012856 packing Methods 0.000 description 1
- 238000011160 research Methods 0.000 description 1
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/60—Software deployment
- G06F8/65—Updates
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/445—Program loading or initiating
- G06F9/44521—Dynamic linking or loading; Link editing at or after load time, e.g. Java class loading
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Computer Security & Cryptography (AREA)
- Stored Programmes (AREA)
Abstract
一种Android系统无感知应用安装升级的方法,包括如下步骤:先检测是否有新的升级包,若有,下载并保存新实体应用包到相关路径,之后升级;先调用宿主应用的attachBaseContext方法;再替换宿主ActivityThread中的所有的Application为实体应用的Application;下一步为替换资源;之后完善执行实体应用的Application的attach()方法以及执行相关的installContentProviders()方法;之后在执行宿主的onCreate()方法时反射执行实体的Application的onCreate()方法;替换完成。
Description
技术领域
本发明涉及移动终端应用领域,尤其涉及一种Android系统无感知应用安装升级的方法。
背景技术
一个android应用发布后如果突然出现bug需要紧急修复的话,普通的打包、发布、安装、升级流程很繁琐而且需要用户介入点击安装,效果很不好。因此免安装升级成为一个比较迫切的需求。免安装升级可以帮助我们在用户无感知的情况下修复应用存在的bug。
目前市面上此类热修复框架不少,比较有名的有支付宝的andfix,nuwa方案,微信的Tinker热修复方案等。
支付宝的andfix采用的是native层hook的方案,主要是通过替换方法的方式进行热修复,好处就是补丁包小而且可以立即生效,但是对平台的兼容性较差,且只能给予方法进行修补。
nuwa方案采用java层替换类的方式来,的兼容性比andfix要好很多,其主要是提前加载插件的类,并将其放在BaseDexClassLoader类端pathList中的dexElements数组的前面。
微信的方案是下载一个差量的dex包,在客户dexElements后台进行patch生成一个完整的包,然后整体将此完整的dex文件直接替换到数组中,微信的方案是在nuwa方案上的一种完善,微信方案下载的补丁包更小,nuwa和微信的方案都需要重启应用。
Andfix和nuwa热修复方案都是只适用于代码修复的,并不包含资源更新,微信tinker号称已经支持资源的加载。
目前市面上还有一种360的免安装方案,就是DroidPlugin,这个方案是既可以加载实体应用的dex也可以加载其资源。DroidPlugin是动态代理了ActivityManager、PackageManager等系统服务在应用中的远程对象,来启动四大组件,使用动态加载dex和资源的方式来加载实体app。
综上,使用类似DroidPlugin的思路来处理热修复的问题,同时又没有动态代理系统各种服务,主要使用动态加载的方式来进行免安装升级,成为目前的研究目标。
发明内容
为解决上述技术问题,本发明提供了一种Android系统无感知应用安装升级的方法,无需动态代理Android系统的各种服务,使用动态加载的方式来进行免安装升级。
一种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类,构造函数:privateZClassLoader(ClassLoaderorgParentClassLoader,StringdexSearchPath,StringlibSearchPath,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(即应用上下文环境)对象将应用资源信息保存起来,系统把生成的资源加载器对象保存到Context Impl实例对象中的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)、至此整个替换过程完成,可以至此使用动态加载的实体应用。
本发明实现了整个apk包的完整静默升级,包含dex文件以及资源文件,可以在用户无感知的情况下通过替换类加载器、替换资源加载器和资源管理器来加载新实体应用安装包中的的指令、数据和其相对应的资源文件,从而实现使用新版本应用的目的。
附图说明
图1为本发明Android系统无感知应用安装升级的方法的流程示意图;
图2为宿主应用安装包结构框架示意图。
具体实施方式
本发明提供了一种Android系统无感知应用安装升级的方法,如图1所示的流程示意图,具体包括如下步骤:
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类去替换安卓应用默认的attachBaseContex类,具体如下:
自定义类加载器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为宿主应用安装包结构框架示意图;
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文件(保存配置的文件)等,进入步骤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);
3)、检测升级:
进行联网,检测是否有新版本实体应用,若有新版本实体应用,进行联网更新,并将新版本实体应用的安装包下载到之前保存实体应用安装包的宿主应用的asset文件夹中,然后进入步骤3),如果没有新的实体应用安装包则直接进行步骤4);
4)、实体应用dex字节码文件(可执行文件)优化:
dex字节码文件(可执行文件)优化是个耗时过程,在宿主应用的清单文件中指定一个服务ZService继承于系统的Service,用于处理可执行文件的优化工作,为宿主应用正常执行,在宿主清单文件中为ZService服务指定一个单独的进程,此进程里的ZService服务里创建了一个自己的类加载器ZClassloader,继承于系统的ClassLoader,然后初始化ZClassLoader,利用ClassLoader初始化时会优化了传入路径apk文件的机制来实现实体应用dex字节码文件的优化,得到安卓设备能直接操作的机器码,优化完成后生成优化后的odex文件(即,optimize-dex文件)等应用下一次启动的时候类加载器如果发现odex文件存在,则就可以直接使用已经优化好的新版本实体应用的可执行文件;
5)、实体应用启动:
5a)、加载实体应用的类:
安卓中类都是通过类加载器ClassLoader加载的,让实体应用的dex文件路径、各种库路径都能被类加载器找到,新创建一个类加载器ZClassLoader,并将其dex文件路径、库路径都为其相应赋值为实体应用的dex文件路径,这样,在使用类加载器加载要使用的各种类的时候就会自动的去相关路径下寻找,具体执行过程是:
判断宿主应用是否被启动,若否,继续等待,若是,宿主应用执行初始化方法attachBaseContext(),在宿主的attachBaseContext()方法中进行实体应用类加载器(classloader)的处理,详细过程如下:
首先调用安卓系统提供的类的getClassLoader()方法得到宿主应用的类加载器OrgClassloader,再调用系统类加载器(classloader)提供的getParent()方法(OrgClassloader.getParent())得到(所述的得到就是调用前述的函数得到其返回值)原始类加载器OrgClassloader的父加载器ParentClassloader,本设计创建了在宿主的attachBaseContext()方法被系统触发调用的时候初始化自己的类加载器ZClassloader用于加载实体应用中使用到的各个类,ZClassloader是继承于系统的Classloader类的,构造函数:privateZClassLoader(ClassLoaderorgParentClassLoader,StringdexSearchPath,StringlibSearchPath,FilecacheDir),传入参数包括宿主应用类加载器(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)被系统调用的时候使用系统方法构造生成新的资源加载器(即new AssetManager()实例),通过AssetManager中的添加方法(即addAssetPath)生成新的资源加载器实例,然后本设计要将此新的资源加载器替换到相应的应用运行时环境中,首先是替换应用全局配置(ActivityThread类实例)中的mActiveResources对象(此对象是个包含了Resources对象的集合)中的各个Resources子对象对应的资源加载器,然后再替换ActivityThread实例中所有的LoadedApk对象中的mResources对象中的资源加载器(mAssets),在ActivityThread中LoadedApk对象主要被系统保存在一个集合mPackages对象中,本设计中则是通过java的反射机制来拿到这个集合,然后一个个的再使用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)、完成应用初始化后,最后一步是执行宿主的onCreate()方法,安卓应用启动的时候一般都是要执行Application实例的onCreate()方法的,所以本设计也需要完成这一步;具体实现也是通过java的反射机制来对应调用执行实体的应用初始化类(即Application)的onCreate()方法;
7)、至此整个替换过程完成,可以至此使用动态加载的实体应用。
本发明技术方案的特征点如下:
1、替换类加载器的方式:本技术方案使用的方法是在应用的bootclassloader和dex加载器之间增加一级类加载器,所增加的类加载器用于加载实体的dex,根据类加载双亲委派机制会优先使用新增加的类加载器,之后才可以支持加载实体应用。
2、加载实体包资源的方式:
目前修改类加载器保证我们可以正常加载实体应用的dex,但是资源还需要加载进来。我们在应用的初始化方法(即attachBaseContext)被系统调用的时候生成新的资源加载器,通过其中的添加方法(即addAssetPath)方法将实体应用文件的路径加入此资源加载器中,然后在获取单例的资源管理器实例,修改其中的应用活动资源(即mActiveResources)中对应的资源加载器,然后再修改应用全局配置(即ActivityThread)中所有的LoadedApk中具体的资源对应的资源加载器(即AssetManager),然后再替换应用上下文环境(即ContextImpl)中的数据段(即mResources)中的资源加载器(即AssetManager)。最后再遍历并缓存实体应用的各个组件的资源信息(即各个Activity、ContentProvider、Service中使用的相关资源信息),然后在实体应用的各个组件具体使用的时候(即安卓系统真正进行执行启动Activity、创建service、创建ContentProvider的时候)进行相应替换,从而完成资源的替换。
本发明跟andfix方法、nuwa方法相比可以加载完整的新实体包以包含其中的资源;使用了增加父classloader的机制来加载dex,反射替换AssetManager的方法替换资源,虽然有一些机型适配的问题,但是在实际使用过程中应用的稳定性还是很可靠的。
跟微信Tinker相比,本方案下载的升级包更大,会更耗流量,但是本方案没有微信的那个升级包原包的patch过程,不会出现合并过程中的占用apu、内存过高等会导致的不稳定的问题;而且本方案支持加载升级包中的资源;
本方案相对360DroidPlugin方案,大大减少代码复杂度、应用稳定性等问题,更为精简地利用动态加载的方式实现免安装升级。
以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应所述以权利要求的保护范围为准。
Claims (1)
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(ClassLoaderorgParentClassLoader,String dexSearchPath,String libSearchPath,FilecacheDir),传入参数包括宿主应用类加载器(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)、至此整个替换过程完成,可以至此使用动态加载的实体应用。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810179483.4A CN108491216B (zh) | 2018-03-05 | 2018-03-05 | 一种Android系统无感知应用安装升级的方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810179483.4A CN108491216B (zh) | 2018-03-05 | 2018-03-05 | 一种Android系统无感知应用安装升级的方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN108491216A true CN108491216A (zh) | 2018-09-04 |
CN108491216B CN108491216B (zh) | 2021-07-13 |
Family
ID=63341201
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201810179483.4A Active CN108491216B (zh) | 2018-03-05 | 2018-03-05 | 一种Android系统无感知应用安装升级的方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN108491216B (zh) |
Cited By (12)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN109784039A (zh) * | 2018-11-28 | 2019-05-21 | 杭州天宽科技有限公司 | 移动终端安全运行空间的构建方法、电子设备、存储介质 |
CN110018866A (zh) * | 2018-11-06 | 2019-07-16 | 蔚来汽车有限公司 | 用户界面主题更新方法、装置、系统、车机及车辆 |
CN110308945A (zh) * | 2019-05-22 | 2019-10-08 | 百度在线网络技术(北京)有限公司 | 插件的动态加载方法和装置 |
CN110851204A (zh) * | 2019-11-08 | 2020-02-28 | 北京字节跳动网络技术有限公司 | 应用启动的方法及装置、应用打包的方法及装置 |
CN111078262A (zh) * | 2018-10-18 | 2020-04-28 | 百度在线网络技术(北京)有限公司 | 应用的热修复方法和装置 |
CN111142922A (zh) * | 2018-11-02 | 2020-05-12 | 阿里巴巴集团控股有限公司 | 应用程序更新方法、装置、终端及服务器 |
CN111367864A (zh) * | 2018-12-25 | 2020-07-03 | 深圳市茁壮网络股份有限公司 | 一种文件的无缝替换方法、读取方法及相关系统 |
CN111399864A (zh) * | 2020-03-16 | 2020-07-10 | 北京五八信息技术有限公司 | 一种安卓系统应用程序基础包生成方法以及生成装置 |
CN111556127A (zh) * | 2020-04-24 | 2020-08-18 | 广东乐心医疗电子股份有限公司 | 一种可穿戴设备升级方法及相关设备 |
CN113010197A (zh) * | 2020-06-11 | 2021-06-22 | 深圳市科脉技术股份有限公司 | 应用静默升级方法、系统、终端设备及存储介质 |
CN113886854A (zh) * | 2021-10-14 | 2022-01-04 | 广州九尾信息科技有限公司 | 一种基于安卓平台权限监控与管理的方法和装置 |
CN115658184A (zh) * | 2022-12-26 | 2023-01-31 | 北京海誉动想科技股份有限公司 | 云应用快速启动的方法、装置、存储介质及电子设备 |
Citations (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102402427A (zh) * | 2010-09-09 | 2012-04-04 | 阿里巴巴集团控股有限公司 | 一种Java应用程序的更新方法及装置 |
US20140223425A1 (en) * | 2011-07-01 | 2014-08-07 | Rodney D. Brown | Plug-In Installer Framework |
CN104123157A (zh) * | 2014-07-17 | 2014-10-29 | 北京京东尚科信息技术有限公司 | 一种移动终端的跨平台业务逻辑定制方法和装置 |
CN104731625A (zh) * | 2015-03-27 | 2015-06-24 | 北京奇虎科技有限公司 | 一种加载插件的方法、装置和移动终端 |
CN106648787A (zh) * | 2016-12-28 | 2017-05-10 | 平安科技(深圳)有限公司 | 一种资源更新的方法及终端 |
CN106775793A (zh) * | 2015-11-23 | 2017-05-31 | 卓望数码技术(深圳)有限公司 | 一种安卓应用免安装启动的方法、装置及终端 |
CN107122200A (zh) * | 2016-02-25 | 2017-09-01 | 博雅网络游戏开发(深圳)有限公司 | 加载插件sdk的方法、系统及客户端 |
US20170255460A1 (en) * | 2015-12-21 | 2017-09-07 | Amazon Technologies, Inc. | Analyzing deployment pipelines used to update production computing services using a live pipeline template process |
-
2018
- 2018-03-05 CN CN201810179483.4A patent/CN108491216B/zh active Active
Patent Citations (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102402427A (zh) * | 2010-09-09 | 2012-04-04 | 阿里巴巴集团控股有限公司 | 一种Java应用程序的更新方法及装置 |
US20140223425A1 (en) * | 2011-07-01 | 2014-08-07 | Rodney D. Brown | Plug-In Installer Framework |
CN104123157A (zh) * | 2014-07-17 | 2014-10-29 | 北京京东尚科信息技术有限公司 | 一种移动终端的跨平台业务逻辑定制方法和装置 |
CN104731625A (zh) * | 2015-03-27 | 2015-06-24 | 北京奇虎科技有限公司 | 一种加载插件的方法、装置和移动终端 |
CN106775793A (zh) * | 2015-11-23 | 2017-05-31 | 卓望数码技术(深圳)有限公司 | 一种安卓应用免安装启动的方法、装置及终端 |
US20170255460A1 (en) * | 2015-12-21 | 2017-09-07 | Amazon Technologies, Inc. | Analyzing deployment pipelines used to update production computing services using a live pipeline template process |
CN107122200A (zh) * | 2016-02-25 | 2017-09-01 | 博雅网络游戏开发(深圳)有限公司 | 加载插件sdk的方法、系统及客户端 |
CN106648787A (zh) * | 2016-12-28 | 2017-05-10 | 平安科技(深圳)有限公司 | 一种资源更新的方法及终端 |
Non-Patent Citations (4)
Title |
---|
JUNHUA: "Android APP修改dex文件实现插件加载", 《HTTPS://ZHUANLAN.ZHIHU.COM/P/25074791》 * |
MR_冯先生: "Android利用腾讯Bugly实现一键多渠道打包+一包热更新全渠道", 《HTTPS://WWW.JIANSHU.COM/P/5D62B2D7D681》 * |
SINGWHATIWANNA: "Android apk动态加载机制的研究", 《HTTPS://BLOG.CSDN.NET/SINGWHATIWANNA/ARTICLE/DETAILS/22597587》 * |
王智恒: "基于动态加载技术的Android插件化开发框架研究与实现", 《中国优秀硕士学位论文全文数据库 信息科技辑》 * |
Cited By (18)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111078262B (zh) * | 2018-10-18 | 2023-04-11 | 百度在线网络技术(北京)有限公司 | 应用的热修复方法和装置 |
CN111078262A (zh) * | 2018-10-18 | 2020-04-28 | 百度在线网络技术(北京)有限公司 | 应用的热修复方法和装置 |
CN111142922B (zh) * | 2018-11-02 | 2023-04-25 | 阿里巴巴集团控股有限公司 | 应用程序更新方法、装置、终端及服务器 |
CN111142922A (zh) * | 2018-11-02 | 2020-05-12 | 阿里巴巴集团控股有限公司 | 应用程序更新方法、装置、终端及服务器 |
CN110018866B (zh) * | 2018-11-06 | 2022-03-15 | 蔚来(安徽)控股有限公司 | 用户界面主题更新方法、装置、系统、车机及车辆 |
CN110018866A (zh) * | 2018-11-06 | 2019-07-16 | 蔚来汽车有限公司 | 用户界面主题更新方法、装置、系统、车机及车辆 |
CN109784039B (zh) * | 2018-11-28 | 2022-04-19 | 杭州天宽科技有限公司 | 移动终端安全运行空间的构建方法、电子设备、存储介质 |
CN109784039A (zh) * | 2018-11-28 | 2019-05-21 | 杭州天宽科技有限公司 | 移动终端安全运行空间的构建方法、电子设备、存储介质 |
CN111367864A (zh) * | 2018-12-25 | 2020-07-03 | 深圳市茁壮网络股份有限公司 | 一种文件的无缝替换方法、读取方法及相关系统 |
CN110308945B (zh) * | 2019-05-22 | 2022-07-05 | 百度在线网络技术(北京)有限公司 | 插件的动态加载方法和装置 |
CN110308945A (zh) * | 2019-05-22 | 2019-10-08 | 百度在线网络技术(北京)有限公司 | 插件的动态加载方法和装置 |
CN110851204A (zh) * | 2019-11-08 | 2020-02-28 | 北京字节跳动网络技术有限公司 | 应用启动的方法及装置、应用打包的方法及装置 |
CN110851204B (zh) * | 2019-11-08 | 2023-04-18 | 北京字节跳动网络技术有限公司 | 应用启动的方法及装置、应用打包的方法及装置 |
CN111399864A (zh) * | 2020-03-16 | 2020-07-10 | 北京五八信息技术有限公司 | 一种安卓系统应用程序基础包生成方法以及生成装置 |
CN111556127A (zh) * | 2020-04-24 | 2020-08-18 | 广东乐心医疗电子股份有限公司 | 一种可穿戴设备升级方法及相关设备 |
CN113010197A (zh) * | 2020-06-11 | 2021-06-22 | 深圳市科脉技术股份有限公司 | 应用静默升级方法、系统、终端设备及存储介质 |
CN113886854A (zh) * | 2021-10-14 | 2022-01-04 | 广州九尾信息科技有限公司 | 一种基于安卓平台权限监控与管理的方法和装置 |
CN115658184A (zh) * | 2022-12-26 | 2023-01-31 | 北京海誉动想科技股份有限公司 | 云应用快速启动的方法、装置、存储介质及电子设备 |
Also Published As
Publication number | Publication date |
---|---|
CN108491216B (zh) | 2021-07-13 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN108491216A (zh) | 一种Android系统无感知应用安装升级的方法 | |
CN112118565A (zh) | 多租户服务灰度发布方法、装置、计算机设备和存储介质 | |
US8555272B2 (en) | System and method for implementing data-compatibility-based version scheme | |
CN102413022B (zh) | 一种应用调试方法和系统 | |
US8464240B2 (en) | Method and system for controlling software version updates | |
US8099472B2 (en) | System and method for a mobile cross-platform software system | |
TWI579769B (zh) | 虛擬機遷移工具 | |
US6314567B1 (en) | Apparatus and method for transferring state data when performing on-line replacement of a running program code and data | |
CN110187910B (zh) | 一种热更新方法、装置、设备及计算机可读存储介质 | |
CN104731625A (zh) | 一种加载插件的方法、装置和移动终端 | |
US11599654B2 (en) | Method and apparatus for authority control, computer device and storage medium | |
CN109725923A (zh) | 一种软件轻量更新方法、装置及设备 | |
US20150012732A1 (en) | Method and device for recombining runtime instruction | |
US11726810B2 (en) | Systemic extensible blockchain object model comprising a first-class object model and a distributed ledger technology | |
CN112783570B (zh) | 基于服务网格的应用迁移方法、系统和介质 | |
CN112685020B (zh) | 动态创建服务接口的方法、装置、电子设备及存储介质 | |
CN114077423A (zh) | 基于移动跨平台的机场app开发容器架构 | |
CN109784039B (zh) | 移动终端安全运行空间的构建方法、电子设备、存储介质 | |
CN107239313A (zh) | Spring应用服务的升级方法和存储介质 | |
CN114168179B (zh) | 微服务管理方法、装置、计算机设备和存储介质 | |
CN113726566A (zh) | 一种服务网关装置 | |
CN111651169B (zh) | 基于web容器的区块链智能合约运行方法及系统 | |
CN115335806A (zh) | 以模块粒度的影子堆栈违规强制 | |
CN113077260A (zh) | 基于区块链的数据访问方法、装置及电子设备 | |
CN115374083A (zh) | 数据源的切换方法、装置、电子设备及存储介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant | ||
PE01 | Entry into force of the registration of the contract for pledge of patent right | ||
PE01 | Entry into force of the registration of the contract for pledge of patent right |
Denomination of invention: A Method for Installing and Upgrading Unconscious Applications in Android Systems Effective date of registration: 20231109 Granted publication date: 20210713 Pledgee: Zhongguancun Beijing technology financing Company limited by guarantee Pledgor: Beijing Zhizhangyi Technology Co.,Ltd. Registration number: Y2023990000550 |