Sophix是否支持任何代码和资源的修复?
几乎都是支持的。但严格来说,也是有一些特殊情况:
首先,SophixManager的initialize被调用之前的代码无法修复。很好理解,热修复框架都没加载起来,怎么可能修复到呢?所以最好的做法是把初始化放在Application.attachBaseContext中。
并且,如果是冷启动加载(一般来说大多数情况都是),调用initialize的所在类无法被修复。快速接入情况下,初始化都会放在入口Application类里面,因此Application是无法修复的。还需注意的是,Application中直接用到的类无法增减方法和字段,原因是在odex之后,Application访问这些类时可能被优化为固定偏移,因此增减方法和字段会导致这些字段的偏移出错。因此建议减少Application直接用到的类,尽量把它们都封装到一个单独类里面,并且使用反射调用可以避免偏移优化。而如果采用稳健接入,可以直接初始化放在单独的StubApplication里面,就可以修复原有的Application了,因此推荐直接使用稳健接入以避免上述问题。
其次,AndroidManifest.xml里面的变动无法修复。因为AndroidManifest.xml是由系统在安装App时解析,因此在运行时App无法修改它的逻辑的。所以四大组件的新增和修改以及其中主题资源等配置都无法修复到。除非用比较hack的方式预先留空和提早注册,而这种方式就显得不够优雅了,不过开发者可以自己在AndroidManifest里面预留些空组件,后续更新时直接添加组件类即可。
对于资源,除了AndroidManifest.xml里面的资源不支持,通知栏图标、启动图标资源、RemoteViews以及getResources().getIdentifier()方式调用的资源,也不支持修复。原因是这类资源是由系统负责展示的,而系统只会在安装包中找资源,不会找到补丁包。尤其需要注意的是,如果通知的图标发生变动,会导致推送通知时因找不到资源而崩溃,因此每次打补丁时务必使得通知的图标不变。
另外,Sophix里热修复框架本身的代码默认不进行修复。
除这上述情况,其他方面的所有热修复都可以得到支持。