Skip to content

Commit

Permalink
修复父类单独Override一个onAttach的情况
Browse files Browse the repository at this point in the history
  • Loading branch information
shifujun committed Apr 19, 2020
1 parent 9f56586 commit 0dc37ac
Showing 1 changed file with 34 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,16 @@ class FragmentSupportTransform : SpecificTransform() {
override fun transform(ctClass: CtClass) {
ctClass.defrost()
//定义将插件Activity还原为ContainerActivity再调用super.onAttach方法的转调方法
val superOnAttach = CtMethod.make("""

val superOnAttach =
fixSuperOnAttachCall(ctClass) {
CtMethod.make("""
private void superOnAttach(ShadowActivity shadowActivity) {
Activity pluginContainerActivity = (Activity)ShadowFragmentSupport.toOriginalContext(shadowActivity);
super.onAttach(pluginContainerActivity);
}
""".trimIndent(), ctClass)
}

//将插件Fragment中对super.onAttach的调用改调到superOnAttach上
val codeConverter = CodeConverterExtension()
Expand All @@ -229,6 +233,35 @@ class FragmentSupportTransform : SpecificTransform() {
*/
ctClass.addMethod(superOnAttach)
}

/**
* Javassist疑似有bug,当super类存在满足签名的方法时,就不会去父类的父类中查找更加准确匹配的方法了。
* 导致当父类只Override了onAttach(Context)方法时,我们定义的superOnAttach方法中的
* super.onAttach(Activity)调用会编译成对onAttach(Context)的调用。这与正常的Javac编译结果不一致。
*
* 因此,在这里如果父类没有定义onAttach(Activity),先为它添加上,make后再移除。
*/
private fun fixSuperOnAttachCall(ctClass: CtClass, make: () -> CtMethod): CtMethod {
val superclass = ctClass.superclass
val needFix = try {
superclass.getDeclaredMethod("onAttach", arrayOf(androidActivity))
false
} catch (e: NotFoundException) {
true
}
return if (needFix) {
superclass.defrost()
val newOnAttachActivity = CtMethod.make("""
public void onAttach(Activity activity) {}
""".trimIndent(), superclass)
superclass.addMethod(newOnAttachActivity)
val result = make()
superclass.removeMethod(newOnAttachActivity)
result
} else {
make()
}
}
})
}

Expand Down

0 comments on commit 0dc37ac

Please sign in to comment.