一种安卓应用的解耦方法与流程

文档序号:14950462发布日期:2018-07-17 22:26阅读:316来源:国知局

本发明涉及软件技术领域,尤其涉及一种安卓应用的解耦方法。



背景技术:

随着智能手机、平板等移动设备的普及,越来越多的用户通过移动设备上安装的移动应用满足日常的生活和工作需求,例如用户通过新闻应用浏览时政新闻、通过购物应用进行在线购物等。

由于现有的应用分发和安装机制的限制,用户必须从应用商店下载完整的应用安装包(例如安卓应用的apk文件),然后安装下载的应用安装包,最后打开应用使用应用的功能。但是,随着应用版本的迭代,开发者在应用上集成了越来越多的功能,应用安装包的体积也越来越大,而用户往往只需要使用其中一小部分的一些常用功能。

越来越复杂的应用导致用户在尝试新的应用的时候需要等待更长的下载和安装时间,同时应用体积的增大也会导致应用启动慢、加载需要更多的内存以及耗费更多电量。上述问题会影响用户使用应用的体验,导致应用的用户流失,给用户和开发者都造成了损失。

鉴于上述现状,业内人员尝试从不同的角度解决相关的问题,但效果均不理想。一方面,可以通过让用户访问网页版的服务使用相关的功能,但是这种方式会受限于网页加载慢、交互差的不足,用户不能获得和移动应用一致的体验;另一方面,开发者通过提供精简版的应用给终端用户较少下载和安装应用的开销,但是这种解决方案需要开发者维护多个版本的应用,会增加开发者额外的开发和维护成本,而且用户如果需要精简版本的应用上没有提供的功能的时候还是需要去下载完整的应用。



技术实现要素:

针对现有技术中存在的问题,本发明的目的在于提供一种安卓应用的解耦方法,能够自动地将现有的安卓应用解耦为基础包和功能包,其基础包包含了应用中用户常用的功能,功能包为其他功能,用户可以根据需要再下载使用。其核心思想是利用静态分析分析安卓页面之间的依赖关系,将常用的页面以及依赖的代码和资源重新打包成基础包,将其他不常访问的页面以及依赖的代码和资源打包成功能包,在用户访问的时候再下载到设备上。在运行时,通过一个应用层的容器,管理解耦后的应用的安装和运行,拦截和模拟安卓运行时环境来运行基础包中的页面,并结合安卓运行时加载机制动态加载功能包中的页面。

为实现上述目的,本发明采取的技术方案为:

一种安卓应用的解耦方法,其步骤为:

获取应用安装文件中的类代码以及应用的资源文件,解析类代码和资源的依赖关系;

确定应用核心页面;

根据依赖关系将核心页面以及依赖的类代码和资源,与应用安装文件中的辅助文件打包为基础包;将核心页面外的各页面及其依赖的代码和资源分别打包为功能包。

进一步地,获取应用安装文件中的类代码以及应用的资源文件,解析类代码和资源的依赖关系包括通过反编译的方式获取应用安装文件中的dex字节码以及应用的资源文件,通过静态分析,获得dex字节码中类和资源的依赖关系。

进一步地,通过静态分析,获得dex字节码中类和资源的依赖关系包括通过静态分析获取所有类之间的调用图,通过对资源文件的分析获取资源文件之间的依赖关系;通过在类代码中进行关键词检索获取类对资源文件的依赖关系。

进一步地,还包括:通过迭代反馈补充将静态分析缺失的类代码文件和资源文件补充进基础包和功能包中,获得可以正确运行的基础包和功能包。

进一步地,核心页面包括启动页面、主页及用户经常访问页面。

进一步地,所述辅助文件包括配置文件和原生库。

进一步地,还包括通过应用容器,管理解耦后的安卓应用的安装、卸载和运行。

进一步地,所述应用容器通过反射的方式,替换系统服务在应用端的binder代理,拦截系统服务的请求并处理。

一种服务器,其包括存储器和处理器,所述存储器存储计算机程序,所述程序被配置为由所述处理器执行,所述程序包括用于执行前述方法中各步骤的指令。

一种存储计算机程序的计算机可读存储介质,所述计算机程序包括指令,所述指令当由服务器的处理器执行时使得所述服务器执行前述方法中的各个步骤。

通过采取上述技术方案,本发明改进了现有安卓应用臃肿的现状,通过解耦应用,拆分为基础包和多个功能包,用户可以按需动态请求下载相应的功能包。同时,本发明提供一个应用层的容器,确保可以成功运行解耦后的应用,使得用户可以享受到和原始应用一致的用户体验,而且得益于解耦后应用体积的减少,可以减少应用加载消耗的内存,从而减少应用打开的时间,减少应用能耗。

附图说明

图1为本发明一实施例中安卓应用的解耦方法的流程示意图。

具体实施方式

为了对本发明实施例中的技术方案进行清楚、完整的描述。下面将结合本发明实施例中的附图,给出一种安卓应用的解耦方法的应用实例。结合图1所示,方法主要包括以下步骤:

1)通过反编译工具反编译应用的apk文件,获取应用的dex字节码文件(即应用的类代码文件),应用的资源文件(包括布局文件、图片资源等),androidmanifest.xml文件和resources.arsc文件(应用的配置文件,分别包含了应用的页面信息和资源信息),c/c++类库(即so文件,为通过c/c++开发的原生类库)。

通过对字节码的静态分析,可以获取所有类之间的调用图,通过对资源文件的分析,可以获取资源文件之间的引用关系(即依赖关系,例如布局文件通过@drawable/name的方式可以引用名为name的图片文件),类似地开发者在代码中通过r.drawable.name的方式引用资源文件,通过在类代码中进行关键词检索可以获取类对资源文件的引用(即依赖关系)。通过上述静态分析,可以获取类之间、资源之间以及类和资源之间的依赖关系。

安卓应用安装文件的反编译和静态分析。利用反编译工具对应用的apk文件进行反编译,获取到应用的资源文件,通过检索资源文件中通过@type/rname的方式引用其他资源的关键词,从而找到资源之间的依赖关系。其中type表示资源类型,例如drawable对应图片资源,layout对应布局文件资源,style对应主题资源等,rname表示资源文件的名称;同时,利用现有的安卓字节码分析工具构建类方法之间的调用图(callgraph),从而获取类之间的依赖关系;最后,通过检索类代码中通过@type/rname或者r.type.rname方式引用资源文件的关键词,获取类代码对资源的依赖关系,例如安卓的activity会通过r.layout.rname的方式指定页面要加载的布局文件。

2)开发者选择部分页面(核心页面,一个页面对应安卓中的activity构件)作为核心功能加入到基础包中,例如开发者可以利用诸如友盟之类的统计分析服务统计用户最经常访问的页面,或者选择自己认为应用中最有用的页面,这些页面称之为核心页面。

其中,一个页面对应一个类,包含一组功能。在安卓应用的开发中是以activity作为前端构件,每个activity对应用户交互的一个页面,每个activity经常集成一类的功能,例如购物应用的商品页面为一个activity,展示了商品的价格、图片等信息,因此本发明以activity页面为粒度来解耦应用。核心页面可以是多个,包含启动页面和主页及用户经常访问页面。即默认把应用的启动页面和主页作为核心页面,因为用户在使用应用的时候都会打开启动页和主页。开发者也可以根据用户的使用数据,选择一些用户经常访问的页面添加进核心页面。

3)根据1)中的分析结果,将上述步骤中确定的核心页面以及依赖的类代码和资源文件,联合apk中的其他文件(包括配置文件如androidmanifest.xml文件、原生类库即c/c++类库等),打包成基础包(新的一个精简版的apk文件)。对于剩下的每个页面,都把该页面以及其依赖的代码文件和资源文件打包为一个功能包(普通的zip压缩包)。

具体而言,对于一个类,如果在静态分析获得的调用图中可以找到一条路径,从某个核心页面对应类的某个方法开始,一直调用到该类的某个方法,并且该路径上的其他方法所在类不是一个功能页面(即除去核心页面之外的activity),就认为基础包的运行依赖该类,把该类加入到基础包中。

类似地,对于某个功能页面,也可以找到它依赖的所有类,并加入到相应的功能包中,这里只需要把依赖且不在基础包中的类添加到功能包中即可,减少冗余。然后,结合静态分析得到的类依赖的资源,把依赖的资源也添加进基础包和功能包中。同样地,功能包中只需要添加不在基础包中的依赖的资源。最后,把安装文件中的其他资源(c/c++库,androidmanifest.xml文件等)也加入到基础包中,重新编译成基础包(为一个普通的apk文件),并直接把功能包中包含的资源压缩成为一个功能包(为一个普通的压缩文件)。

4)由于现有静态分析技术的不足,对于上一步生成的基础包和功能包会有依赖的类没有分析到的问题,导致在运行时会抛出缺少类或者资源的异常信息,基础包和功能包不能正确运行,故可考虑提供迭代反馈补充的方法进行优化,将静态分析缺失的代码文件和资源文件补充进基础包和功能包中,获得可以正确运行的基础包和功能包。通过运行解耦后的应用,收集系统抛出的缺少类或者资源的信息,然后补充到相应的基础包或者功能包中,重复上述步骤直到没有异常抛出。这样就可以保证用户可以正确运行解耦后的应用,而不会抛出异常信息。

5)通过一个应用容器,用来管理解耦后应用的安装卸载以及运行,使得用户可以有和使用原始应用一致的用户体验。该应用容器通过反射的方式,替换系统服务在应用端的binder代理,拦截系统服务的请求并处理,从而达到未安装解耦应用也能正确运行的效果。同时,当检测到用户希望打开一个本地没有安装的页面,会向服务器请求包含该页面的功能包,下载完成后将资源文件合并到基础包中,并通过安卓的动态加载机制将功能包中的代码加载进应用程序的运行进程中,最后成功打开目标页面。在之后的访问中,不需要再重复下载包含该页面的功能包,而是直接从本地加载。

应用解耦产生的基础包和功能包,分别包含用户常用的功能以及不常用的功能,为了让用户能够享受和原始应用一致的用户体验,不破坏用户使用应用的习惯和操作方式,而运行时的应用容器则能够管理解耦应用的安装和运行。

该应用容器实际上是一个普通的安卓应用,用户只需要安装该应用,然后在该应用中打开基础包,该容器会完成基础包的安装,然后打开基础包,用户就像使用一个普通的安卓应用。

当用户的操作触发应用打开一个功能页面的时候,该容器会检测本地是否已经有相应的功能包:如果没有则从服务器下载包含该功能页面的功能包,将功能包中的资源合并到基础包中,然后通过安卓的动态加载机制,将功能包中的页面以及依赖的其他代码加载入内存中;否则,直接通过安卓的动态加载机制,将功能包中的页面以及依赖的其他代码加载入内存中。最后,就能够成功启动功能页面。该容器在打开一个新的解耦应用的时候,会fork一个子进程来运行解耦后的应用,然后通过进程注入的方式,通过发射修改安卓系统服务在应用进程中的binder代理,从而达到拦截和控制解耦应用的运行。

另外,上述方法可通过可执行程序的形式实现,程序可以存储于计算机可读存储介质,也可以通过处理器执行。

下面选择豆瓣电影安卓版应用为例,模拟用户在实际生活中的一个实际需求,对上述实施例描述的方法的实现过程及运行结果进行具体说明,将豆瓣电影的启动页(广告页)、首页、电影详情页作为核心页面。

首先,通过反编译和静态分析技术将豆瓣电影应用解耦为一个基础包和多个功能包(演员详情页、登陆页面、购票页面等)。并通过迭代反馈的补充方法将静态分析缺失的类和资源补充到基础包和功能包中,得到可正确运行的基础包和功能包。原应用为4mb大小,解耦后的基础包只有2.3mb(基础包只包含了启动页和首页),以及10个包含常用页面的基础包(包括演员详情页、登陆页面、购票页面等,每个为几十kb到几百kb不等)。

然后,用户安装本发明提供的运行时应用容器的应用到手机上。用户打开该应用,在其中点击豆瓣电影的图标。该容器应用会下载解耦产生的豆瓣电影的基础包,模拟应用安装过程做一些初始化的工作,并启动豆瓣电影应用。

最后,用户在启动的应用上进行信息浏览,就像在普通的豆瓣电影应用中一样。例如,点击首页中的电影缩略图,进入到电影详情页,浏览电影的简介信息。当用户点击电影详情页中展示的某个演员的信息项的时候,会尝试打开演员详情页。由于该页面的不在本地,因此容器应用会向服务器请求包含该页面的功能包,下载结束后动态加载代码到内存中,然后成功打开演员详情页。当用户的操作触发其他功能页的时候,会进行类似的操作。

与现有的应用相比,上述实施例有效减少了用户首次使用应用下载的安装包大小(4mb缩减到2.3mb),而且没有破坏用户使用该应用的操作逻辑和体验。其次,由于应用大小的缩减,启动应用的内存消耗平均降低了12.4%,启动时间缩短了16.5%。在首次访问功能页面的时候,由于冷加载过程需要下载功能包以及合并资源,有少量的开销,但是再次访问的时候由于本地缓存的作用,可以达到像使用完整版本的应用一致的效果。

显然,所描述的实施例仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1