【玩转Android自动化】系列文章基本完结了,做了这么多功能后其实发现我们所做的一切都是依赖于当前版本页面的元素id或者text的唯一性去做的,一旦微信升级后这些id或text变动的话这些功能就全部失效了,所以接下来我们的重点工作要放在版本适配上.
为什么要适配
- 我们都知道微信隔一段时间会更新一些版本,有大版本也有小版本,按照以往的经验,随着版本更新页面元素有时候会发生变化,一段某个版本的页面元素变化了,我们之前做的所有功能就全部失效了,我们花了这么多时间做的东西总不能因为微信升级就废弃掉吧,所有微信版本适配工作刻不容缓。
如何适配
-
通过前边系列文章讲解基本上了解了我们的每个页面都会定义一些枚举,里边放的就是元素节点的
id和text以及这个节点是解释说明,使用的地方只要引用当前类中的值就可以了,那么为了适配不同版本,要怎么去把这块代码抽离出来呐。 -
我们期望的是在每个功能页面类中定义一个接口,接口中定义一些接口属性,然后在定义一个版本实现类去逐个实现所有用到的节点,然后再按照版本号去分类。最后在定义一个全局变量表明当前用的是哪个版本,使用的地方根据传入的当前版本号去找到对应版本的节点。
-
有了上边的思路我们先在首页实验一番,先定义一个接口
Node
interface Node {
val homeBottomNavNode: NodeInfo
val bottomNavContactsTabNode: NodeInfo
val bottomNavMineTabNode: NodeInfo
val homeRightTopPlusNode: NodeInfo
val createGroupNode: NodeInfo
}
- 在定义一个微信节点的实现类
WeChatNodesImpl去实现接口定义的属性
enum class WeChatNodesImpl(val version: String) : WXHomePage.Node {
WechatVersion_8_0_40("8.0.40") {
//首页
override val homeBottomNavNode = NodeInfo("", "com.tencent.mm:id/fj3", "首页底导布局")
override val bottomNavContactsTabNode = NodeInfo("通讯录", "com.tencent.mm:id/f2s", "首页底导【通讯录】tab")
override val bottomNavMineTabNode = NodeInfo("我", "com.tencent.mm:id/f2s", "首页底导【我】tab")
override val homeRightTopPlusNode = NodeInfo("", "com.tencent.mm:id/grs", "首页右上角【加号】按钮")
override val createGroupNode = NodeInfo("发起群聊", "com.tencent.mm:id/knx","点击首页右上角【加号】按钮后弹框中的【发起群聊】按钮")
}
}
注意:这里之所以要定义成枚举类,是为了列举多版本方便。
-
使用的地方直接调用
WeChatNodesImpl.WechatVersion_8_0_40.homeBottomNavNode.nodeId,有新版本的时候调用WeChatNodesImpl.WechatVersion_x_x_x.homeBottomNavNode.nodeId,但是这种方式有个很大的弊端就是每次只支持一个版本。不同的用户可能使用的版本不一样,这样只支持一个最新版的话就不够友好了。 -
刚才也说了我们定义的实现类是枚举,这样的话我们传入某个指定的版本号,就可以从枚举中找到对应的版本的枚举,这样的话就把问题变成
如何根据传入的版本号去自动获取对应版本的实现. -
我们把枚举值转换成key是版本号,value是对应的map,然后根据传入的版本号从map中取出对应的value即可
var currentWXVersion = "8.0.40"
private val wechatNodesImplMap by lazy { WeChatNodesImpl.values().associateBy { it.version } }
val currentWechatNodes: WeChatNodesImpl
get() = wechatNodesImplMap[currentWXVersion] ?: error("未适配的微信版本, currentWXVersion: $currentWXVersion")
-
具体使用的地方调用
currentWechatNodes.homeBottomNavNode.nodeId就可以了,这样就会自动根据当前设置的版本号取到对应的节点了。 -
其实我们还可以使用动态代理,去代理
Node接口,感兴趣的可以了解一下
inline fun <reified Nodes> nodeProxy(): Nodes {
val nodesClass = Nodes::class.java
val proxy =
Proxy.newProxyInstance(nodesClass.classLoader, arrayOf(nodesClass)) { _, method, args ->
val impl = currentWechatNodes
method.invoke(impl, *args.orEmpty())
}
return proxy as Nodes
}
companion object : Nodes by nodeProxy()
最终效果
- 通过上边的方法已经做好了版本适配工作了,来看下效果吧
enum class WeChatNodesImpl(val version: String) : WXHomePage.Nodes {
WechatVersion_8_0_40("8.0.40") {
//首页
override val homeBottomNavNode = NodeInfo("", "com.tencent.mm:id/fj3", "首页底导布局")
override val bottomNavContactsTabNode = NodeInfo("通讯录", "com.tencent.mm:id/f2s", "首页底导【通讯录】tab")
override val bottomNavMineTabNode = NodeInfo("我", "com.tencent.mm:id/f2s", "首页底导【我】tab")
override val homeRightTopPlusNode = NodeInfo("", "com.tencent.mm:id/grs", "首页右上角【加号】按钮")
override val createGroupNode = NodeInfo("发起群聊","com.tencent.mm:id/knx","点击首页右上角【加号】按钮后弹框中的【发起群聊】按钮")
},
WechatVersion_x_x_x("x.x.x") {
//首页
override val homeBottomNavNode = NodeInfo("", "com.tencent.mm:id/fj3", "首页底导布局")
override val bottomNavContactsTabNode = NodeInfo("通讯录", "com.tencent.mm:id/f2s", "首页底导【通讯录】tab")
override val bottomNavMineTabNode = NodeInfo("我", "com.tencent.mm:id/f2s", "首页底导【我】tab")
override val homeRightTopPlusNode = NodeInfo("", "com.tencent.mm:id/grs", "首页右上角【加号】按钮")
override val createGroupNode = NodeInfo("发起群聊","com.tencent.mm:id/knx", "点击首页右上角【加号】按钮后弹框中的【发起群聊】按钮")
}
}
温馨提示:每次使用的时候从已经适配的版本列表中选择自己手机里安装的微信版本,
选择好版本号后在使用对应的功能,当前已适配的版本号是8.0.40
完结
- 至此关于
Android自动化的全系列文章算是暂时告一段落了,相信通过这几篇文章的学习你已经对其非常了解了,建议大家根据文章顺序多阅读几遍加深理解。后边如果有更好玩的功能也欢迎在Issues中提出,或者打在评论区,如果好玩咱就继续搞哈!
感兴趣的可以下载demo体验一下,在阅读源码过程遇到任何问题欢迎提Issues,如果对你有帮助,希望动动你的发财小手点个赞呗
还没有阅读过【玩转Android自动化】系列文章的可以根据下边列举的目录顺序阅读哦