符合中小企业对网站设计、功能常规化式的企业展示型网站建设
本套餐主要针对企业品牌型网站、中高端设计、前端互动体验...
商城网站建设因基本功能的需求不同费用上面也有很大的差别...
手机微信网站开发、微信官网、微信商城网站...
这篇文章将为大家详细讲解有关小程序如何实现多进程,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
创新互联建站主要从事成都做网站、网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务石狮,10年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:13518219792小程序这个名词相信大家已经不陌生了,继微信之后,阿里巴巴、百度、头条等大厂相继实现了自己的小程序。小程序是一种全新的开放能力,开发者能够快速开发出小程序并集成进宿主,实现推广等目的。
从使用角度看,小程序有轻量,易用等特点;
从技术角度,以Android端为例,小程序有部分组件原生化、UI和逻辑线程隔离、小程序之间进程隔离等等。
下面主要从小程序进程隔离角度出发,分析BAT的小程序多进程的实现方案,并自己实现一个小程序的多进程。
多进程,顾名思义,即每一个小程序都是一个单独的进程。这个效果只在Android端独有。那为什么我们希望小程序之间实现进程隔离呢?原因大致有三点:
由于是单独进程,无论小程序内部因为何种原因的崩溃,对主进程都没有影响,增强用户体验。
由于每个进程都有一片单独的内存区域,小程序不会占用主进程的内存,降低了内存溢出的风险。
由于不同进程间的内存是隔离的,当同时开启多个小程序时,内存变量、参数等数据互不影响,也可达到一个解耦的目的。
既然是分析多进程这种用户感知不强烈的技术点,我们需要通过一些工具或命令。
进程分析
首先,我们把微信完全杀死又重新开启,然后通过 adb shell ps | grep com.tencent.mm 命令,可以查看正在运行的进程名称和数量,其中 grep com.tencent.mm 是过滤微信相关的进程,因为微信的包名是com.tencent.mm。此时进程运行状况如下图:
此时我们只能看出微信从完全关闭到启动,开启了6个进程,但是还看不出这些是否与小程序相关。于是,我们打开一个小程序,再次执行 adb shell ps | grep com.tencent.mm 命令,此时进程运行状况如下图:
对比之后,就可以做一些分析了。其中,com.tencent.mm是主进程,com.tencent.mm:push应该是与推送相关的进程,com.tencent.mm.tools和com.tencent.mm:toolsmp应该都是一个类似于Helper的相关进程,因此我认为最有可能的是com.tencent.mm:appbrand2,因为这个命名比较特殊,前面分别有appbrand0和appbrand1两个进程出现过。那么为什么新开的第一个小程序,反而多出来的进程时appbrand2呢?我个人猜测这与微信小程序的预加载有关系,很有可能是,这个进程是空的,只是先fork出来,并没有做过多的事情,真正承载我们开启的那个小程序的进程,很有可能不是这个appbrand2。那么如何验证呢?进入第二步,Activity分析。
首先打开一个小程序,然后通过 adb shell dumpsys activity activities 命令,可以看到所有栈内的Activity信息,滑到顶部,查看正在与用户交互的Activity信息,如下图:
关键的信息我已经用红色圈了出来,processName=com.tencent.mm:appbrand0,realActivity=com.tencent.mm/.plugin.appbrand.ui.AppBrandUI,这大致已经验证了我们刚才的猜想,即:
com.tencent.mm:appbrand系列,是与小程序相关的进程。
微信预加载2个空进程作为预加载,避免用时再fork进程,耗时过长影响用户体验。
为了进一步验证猜想是否正确,我下载了微信最新版本的apk,进行了逆向操作,也就是第三步,分析apk。
反编译的方法大家自行搜索,这里就不赘述了。我们打开反编译后的AndroidManifest.xml文件,搜索刚才的的Activity名称,结果如下:
得到的信息与刚才一致。然而,我们又发现了另一个问题,那就是AppBrandUI还有另外4个兄弟,即AppBrandUI1,AppBrandUI2,AppBrandUI3,AppBrandUI4,而这四个Activity的名称与绑定的进程,又能够与一开始的appbrand对应起来,经过试验,我发现微信最多只可以启动5个小程序,而这些小程序的载体就是这5个Activity,不断轮询,超过5个时,将第一个结束掉。这样,我们就基本可以确定,微信是通过apk内置的5个Activity,来实现小程序的多开与进程隔离的。
因此,理论上这5个Activity应该是除了进程不同,内部逻辑应该都是相同的,于是我们继续验证,反编译代码后找到AppBrandUI1这个Activity,结果如下图:
AppBrandUI2,AppBrandUI3,AppBrandUI4与此完全一样,都是继承了AppBrandUI,做了极少的事,由于微信代码混淆过,我们无法看出那几行代码具体做了什么,但是基本可以理解为完全复用。至于为什么分开写,而不是复用同一个,我猜测原因可能有二:
由于语法限制,为Activity开辟进程需要在AndroidManifest.xml中预先配置
2. 微信不仅将小程序进程隔离,并且还进行了栈隔离,当我们同时开启多个小程序时,长按Home键,可以发现存在多个小程序任务卡片,这种效果同样需要在AndroidManifext.xml中配置taskAffinity属性,这在上图中也有体现。
另外,我还注意到,微信在AndroidManifest.xml中配置了这样的Receiver:
这种Receiver共有5个,每个小程序进程有一个,其它4个只是继承了这个AppBrandTaskPreloadReceiver,由于混淆的原因,无法看出具体做了什么事,但是通过名字判断,是实现小程序进程预加载的,空闲时开启这个广播,至少可以提前开启进程,避免用时再加载耗时过长影响用户体验。
同样的,我分析了百度和支付宝的apk,通过命令和反编译等方法,发现他们的方案几乎一样,只是预加载的数量等一些小细节不同,感兴趣的同学可以自己逆向之后做对比。
分析总结
1. 微信对每个小程序都做了进程隔离和栈隔离,互不影响。
2. 实现这一功能的载体Activity是预先配置在AndroidManifest.xml中的。
3. 通过某种方法,微信将小程序的大运行数量控制在5个。
4. 微信对多进程做了一些优化,已知的是预加载2个空进程。
5. BAT等大厂的小程序多进程方案大同小异。
一. Application初始化
Android的app在开启多进程时,每开启一个进程,Application都会重新创建,也就是onCreate函数会被调用,如果没有做进程判断,所有东西会初始化多次,造成卡顿或意料之外的bug。
二. 分配与管控
由于进程之间的内存无法共享,小程序的生命周期需要在某一个进程中维护,不然无法做到动态分配进程和栈,而这个进程选择主进程最为合适。因此需要创建一个管理器,这个管理器负责以下几件事:
1. 接收外界开启、关闭等对小程序的操作
2. 合理的为接收到的请求分配空闲的进程
3. 接收远程小程序的生命周期回调并通过某个uuid进行维护
4. 在空闲时预加载进程
5. 根据设置的可开启的大小程序数量,对进程进行新建、销毁等操作
6. 所有这些管理和维护的操作,对小程序接入者都应是透明的,无需关心具体实现流程,仅在需要时开启小程序即可。
三. 进程生命周期问题
Android系统对于内存有一套自己的管控机制,当内存较为紧张时会在不做任何通知的情况下kill掉活跃度较低的进程,至于进程活跃程度,就与Android的进程保活有关了,可通过设置前台进程、唤醒等方式去尽量保活。但是无论应用端再怎么做,都无法逾越操作系统的权限,系统在某些情况下依然会把进程杀死来保证整个系统的正常运行。因此,开发时需要做容错处理,不能仅以Activity的onDestroy回调为准,因为一旦出现系统级的回收,很可能导致整个分配管理器的错乱。
四. 通讯
通信又分为两个方面,第一,小程序进程与app主进程是隔离的,需要进程间的IPC通信;第二,小程序的本质是一个web容器,这就少不了js与原生的通信,需要jsbridge。下面分别说一下这两个方面。进程通信:
IPC的实现已经不是什么问题,这里仅说几个需要注意的点:
1. 通信一定是双向的,无论哪个进程,最好绑定同一个服务,方便数据的维护。
2. 由于通信较为频繁,建议使用基于Binder的通信机制,可以提高运行效率。
js与原生通信:
js与原生通信一定是通过jsbridge,最好做法是将原生方法的实现写在主进程,分布在不同进程的小程序向主进程请求某个bridge的实现结果,主进程根据相应的参数去执行并返回结果,类似于一套CS的架构。即小程序客户端无需关心具体操作,只关心结果并响应给web端。
关于小程序如何实现多进程就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。