以服务于中国广大创业者为己任,立志于做最好的创业网站。

标签云创业博客联系我们

导航菜单

apk,小吃视频apk

  

  #外挂前世。   

  

  插件技术是安卓高级工程师必须具备的技能之一。从2012年提出插件概念(安卓版)到2016年插件的绽放,可以说插件技术引领了安卓技术的进步。   

  

  插件技术起源于不用安装就能运行apk的思想,可以理解为插件。启用插件的应用可以在运行时加载和运行插件,这样就可以将应用中一些不常用的功能模块做成插件。一方面减小了安装包的大小,另一方面可以动态扩展应用的功能。要实现插件,我们主要解决以下三个问题:   

  

  *插件中的代码加载和与主项目的相互调用。   

  

  *插件中资源的加载以及与主项目的相互访问。   

  

  *四个组件的生命周期管理。   

  

  下面是一些知名的开源插件框架,按照出现时间排序。通过研究它们的实现原理,我们可以大致看到插件技术的发展。根据实现原则,这些框架可以分为三代。   

  

     

  

  第一代:动态负载-   

  

  Apk首先使用ProxyActivity作为静态代理技术,ProxyActivity控制插件中PluginActivity的生命周期。这种方法有明显的缺点,插件中的活动必须继承PluginActivity,并且在开发过程中应该小心处理上下文。而DroidPlugin通过Hook系统服务启动插件中的Activity,使得开发插件的过程和开发普通app的过程没有什么不同。然而,由于hook中的系统服务太多,因此极其复杂和不稳定。   

  

  第二代:为了同时实现插件开发的低侵入性(像开发普通app一样开发插件)和框架的稳定性,实现原则是选择尽可能少的钩子,通过在清单中嵌入一些组件来实现四个组件的插件化。此外,每个框架都根据其设计思路进行了不同程度的扩展,其中Small已经成为一个跨平台、基于组件的开发框架。   

  

  第三代:VirtualApp功能相当强大,可以完全模拟App的运行环境,实现app的免安装运行和双开技术。Atlas是阿里今年开发的一个结合组件化和热修复技术的app基础框架。它广泛应用于阿里系的各种应用,号称是一个容器化的框架。   

  

  #插件对于安卓开发的意义。   

  

  近年来,一线互联网厂商几乎形成了对移动互联网的垄断,app的功能也越来越多,如以下美团、支付宝(近期被查垄断问题(手动狗头)):   

  

     

  

  每个app集成了很多功能入口,包括“美食”、“电影”、“外卖”和"打车"。   

  

  “等等,其实每个入口都是一个app,它只集成到这些入口中。想想如果没有插件技术,美团、淘宝等应用会有多大。或者对于用户来说,如果没有插件,应该在手机上再下载多少个应用?   

  

  无论是对于美团、阿里等互联网IT公司,还是对于安卓用户来说,插件技术的出现都具有里程碑式的意义。对于安卓开发者来说,插件技术已经成为高级安卓工程师必备的技能之一。   

  

  #如何学习插件。   

  

  #开始。   

  

  首先我们要知道,插件技术属于一个比较复杂的领域。复杂性在于它涉及的知识点范围很广,不仅仅是上层做应用架构的能力,还要求我们了解安卓。   

  

  系统底层的知识需要一定程度的了解。以下是相关知识点的简要列表:   

  

     

  

  首先,我们要介绍一下Binder。我们都知道安卓多进程通信的核心是Binder,没有它真的很难移动。粘合剂   

  

  说到双层技术,你可以把它想象成一种中介模式。Binder充当客户端和服务器之间的中介。如果要实现四个组件的插件,需要使用Binder。   

  

  做出改变,宾德。   

  

  没有办法修改服务器的内容,只能修改客户端的代码,四个组件的客户端各不相同,需要进一步研究。学习宾得最好的方法是AIDL。   

  

  网上有很多这方面的信息,最简单的方法就是从。   

己写个 aidl 文件自动生成一个 Java

  

类,然后去查看这个Java类的每个方法和变量,然后再去看四大组件,其实都是跟 AIDL 差不多的实现方式。

  

其次,是 App 打包的流程。代码写完了,执行一次打包操作,中途经历了资源打包、 Dex 生成、签名等过程。其中最重要的就是资源的打包,即 AAPT

  

这一步,如果宿主和插件的资源id冲突,一种解决办法就是在这里做修改。

  

第三, App 在手机上的安装流程也很重要。熟悉安装流程不仅对插件化有帮助,在遇到安装 Bug 的时候也非常重要。手机安装 App

  

的时候,经常会有下载异常,提示资源包不能解析,这时需要知道安装 App 的这段代码在什么地方,这只是第一步。第二步需要知道, App

  

下载到本地后,具体要做哪些事情。手机有些目录不能访问, App

  

下载到本地之后,放到哪个目录下,然后会生成哪些文件。插件化有个增量更新的概念,如何下载一个增量包,从本地具体哪个位置取出一个包,这个包的具体命名规则是什么,等等。这些细节都必须要清楚明白。

  

第四,是 App 的启动流程。 Activity 启动有几种方式?一种是写一个 startActivity ,第二种是点击手机 App ,通过手机系统里的

  

Launcher 机制,启动 App 里默认的 Activity 。通常, App

  

开发人员喜闻乐见的方式是第二种。那么第一种方式的启动原理是什么呢?另外,启动的时候,Main 函数在哪里?这个 Main

  

函数的位置很重要,我们可以对它所在的类做修改,从而实现插件化。

  

第五点更重要,做 Android 插件化需要控制两个地方。首先是插件 Dex 的加载,如何把插件 Dex 中的类加载到内存?另外是资源加载的问题。插件可能是

  

Apk 也可能是 so 格式,不管哪一种,都不会生成 R.id ,从而没办法使用。这个问题有好几种解决方案。一种是是重写 Context 的

  

getAsset 、 getResource 之类的方法,偷换概念,让插件读取插件里的资源,但缺点就是宿主和插件的资源 id 会冲突,需要重写 AAPT

  

。另一种是重写 AMS中保存的插件列表,从而让宿主和插件分别去加载各自的资源而不会冲突。第三种方法,就是打包后,执行一个脚本,修改生成包中资源id。

  

第六点,在实施插件化后,如何解决不同插件的开发人员的工作区问题。比如,插件1和插件2,需要分别下载哪些代码,如何独立运行?就像机票和火车票,如何只运行自己的插件,而不运行别人的插件?这是协同工作的问题。火车票和机票,这两个

  

Android 团队的各自工作区是不一样的,这时候就要用到 Gradle

  

脚本了,每个项目分别有各自的仓库,有各自不同的打包脚本,只需要把自己的插件跟宿主项目一起打包运行起来,而不用引入其他插件,还有更厉害的是,也可以把自己的插件当作一个

  

App 来打包并运行。

  

上面介绍了插件化的入门知识,一共六点,每一点都需要花大量时间去理解。否则,在面对插件化项目的时候,很多地方你会一头雾水。而只要理解了这六点核心,一切可迎刃而解。

  

# 实现原理

  

在Android中应用插件化技术,其实也就是动态加载的过程,分为以下几步:

  

* 把可执行文件( .so/dex/jar/apk 等)拷贝到应用 APP 内部。

  

* 加载可执行文件,更换静态资源

  

* 调用具体的方法执行业务逻辑

  

Android 项目中,动态加载技术按照加载的可执行文件的不同大致可以分为两种:

  

* 动态加载 .so 库

  

* 动态加载 dex/jar/apk文件(现在动态加载普遍说的是这种)

  

第一点, Android 中 NDK 中其实就使用了动态加载,动态加载 .so 库并通过 JNI 调用其封装好的方法。后者一般是由 C/C++

  

编译而成,运行在 Native 层,效率会比执行在虚拟机层的 Java 代码高很多,所以 Android 中经常通过动态加载 .so

  

库来完成一些对性能比较有需求的工作(比如 Bitmap 的解码、图片高斯模糊处理等)。此外,由于 .so 库是由 C/C++

  

编译而来的,只能被反编译成汇编代码,相比中 dex 文件反编译得到的 Smali 代码更难被破解,因此 .so 库也可以被用于安全领域。

  

其二,“基于 ClassLoader 的动态加载 dex/jar/apk 文件”,就是我们指在 Android 中 动态加载由 Java 代码编译而来的

  

dex 包并执行其中的代码逻辑, 这是常规 Android 开发比较少用到的一种技术 ,目前说的动态加载指的就是这种。

  

Android 项目中,所有 Java 代码都会被编译成 dex 文件,Android 应用运行时,就是通过执行 dex

  

文件里的业务代码逻辑来工作的。使用动态加载技术可以在 Android 应用运行时加载外部的 dex 文件,而通过网络下载新的 dex 文件并替换原有的

  

dex 文件就可以达到不安装新 APK 文件就升级应用(改变代码逻辑)的目的。

  

所以说,在 Android 中的 ClassLoader 机制主要用来加载 dex 文件,系统提供了两个 API 可供选择:

  

* PathClassLoader:只能加载已经安装到 Android 系统中的 APK 文件。因此不符合插件化的需求,不作考虑。

  

* DexClassLoader:支持加载外部的 APK、Jar 或者 dex 文件,正好符合文件化的需求,所有的插件化方案都是使用 DexClassloader 来加载插件 APK 中的 .class文件的。

  

# 最后

  

插件化的学习肯定不是只要掌握以上的“入门知识”和“实现原理”就可以了的,还需要去学习主流插件化框架的原理以及多去实战应用。

  

由于篇幅原因,也为了方便朋友们更加系统的学习插件化,我整理了一份《高级Android插件化强化实战(附源码)》PDF和《360插件化技术实战》学习视频,有需要的同学可以点赞+评论后点,后台私信我获取。

  

# 直达领取通道

  

  

高级Android插件化强化实战目录

  

  

滴滴插件化实战解析

  

  

爱奇艺插件化实战解析

  

  

插件化学习视频

  

马上就是2021年,也即将迎来元旦的小假期,这里提前预祝大家元旦节快乐,在新的一年里心想事成、万事如意、步步高升。如果在这个小假期里,刚好又因为难求的车票、拥挤景区、而“被迫”宅家闲着没事的话,那不如趁着新年的开始,悄悄的学习一套插件化技术,来惊艳所有人吧!新的一年,加油,打工人!

  

# 需要以上学习资料的同学,可以在后台私信我获取!