优化建议:Shadow框架的数据库表shadowPluginManager中,数据太多时会导致插件启动慢
大佬好。 ### 我们线上APP已经接入Shadow框架已有3年了,最近线上有用户反馈,每次启动插件模块时必须要等待7秒才能进入插件模块。 经过我们的分析和复现,最终定位到耗时的地方是在这个类SamplePluginManager中onStartActivity方法的下面这句代码:InstalledPlugin installedPlugin = installPlugin(pluginZipPath, null, true);,如下
private void onStartActivity(final Context context, Bundle bundle, final EnterCallback callback) {
//其他代码
........
InstalledPlugin installedPlugin
= installPlugin(pluginZipPath, null, true);//这个调用是阻塞的,每次执行都耗时7秒
//其他代码
..........
}
进而分析是在类FastPluginManager.java的installPlugin方法中以下两行代码onInstallCompleted(pluginConfig); 和 return getInstalledPlugins(1).get(0);比较耗时,如下:
public InstalledPlugin installPlugin(String zip, String hash, boolean odex) throws IOException, JSONException, InterruptedException, ExecutionException {
//其他代码
.....................
onInstallCompleted(pluginConfig); //经过测试,耗时3秒左右
return getInstalledPlugins(1).get(0); //经过测试,耗时3秒左右
}
这两句代码的意思,看上去是,先将插件信息插入到数据库中,需要使用的时候再从数据库中查询出来。并且每次执行启动插件都会执行一次,每次执行会插入4行插件的信息数据到数据库表shadowPluginManager中。 我们把用户启动插件慢的设备拿回来分析,发现他的设备APP目录下数据库该shadowPluginManager表中数据有9万多条。所以我们推测启动慢是因为,数据表数据量大的情况下,每次启动插入插件信息和查询插件信息速度会变慢,进而导致启动插件的速度变慢。 经过我们自测验证,确认就是这个原因。
目前我们解决这个启动慢的问题的方案是,每次下载更新最新的插件时,我们会主动先清理 数据库shadowPluginManager表中所有的数据,然后再安装新的插件,从而达到启动时插入和查询速度变快的目的。
请问, 1,我们目前的这种解决方案会有什么风险没? 2,随着用户启动插件的次数变多,数据库shadowPluginManager表中数据确实会越来越多,这块是否可以优化?
谢谢!
粗看9万行数据是明显意料之外的吧。难道是你发了9万个版本了?
粗看9万行数据是明显意料之外的吧。难道是你发了9万个版本了?
不是意外,线上已经很多用户反馈慢了,拿了几台设备都是几万条数据以上。
我们启动插件方法,是参考demo启动方法:SamplePluginManager 类的onStartActivity方法。每次用户点击启动插件,都会执行onStartActivity方法。经过启动插件模块时,观察数据库表发现,onStartActivity方法中这句代码:InstalledPlugin installedPlugin= installPlugin(pluginZipPath, null, true); 每次执行后,数据库shadowPluginManager表中都会被插入4条数据。
如图:
请问我们启动插件模块的方法有问题吗?
那就没什么奇怪的了。你每次启动插件都重新安装了一次插件zip包。
你需要的是先查询已安装的插件信息,按照你的业务升级逻辑判断要不要启动已安装的插件。
建议框架层也做个优化,如果是重复的数据就不重复插入了,相当于做个兜底机制,可以避免不必要的问题。
这个installPlugin方法作为基础的原子功能,额外添加某种去重逻辑是不合适的。假如相同uuid的part不被重复插入数据库,那可能无法满足回退到旧版本的场景。或者还可能存在考虑不到的情况。所以基础接口最好不做分支逻辑。
避免重复调用这个接口本身是比较容易的,并且是否调用和业务升级逻辑也是强相关的。