如果您想专门摆脱某些super.theMethodIAmIn()
调用,实际上可以非常类似于“甚至更好”的情况,如果您在扩展的类中执行这些超级调用:
public class BetterActivity extends Activity {
@Override
protected final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
onCreateNoSuper(savedInstanceState);
}
// could be abstract as well.
protected void onCreateNoSuper(Bundle savedInstanceState) {}
}
现在你可以做
class MyActivity extends BetterActivity {
@Override
protected void onCreateNoSuper(Bundle savedInstanceState) {
// done.
}
}
缺点:
- 您必须使用不同的方法名称。
- 如果有人直接调用那些派生的(
onCreateNoSuper
)方法而不是调用onCreate
. Android 的方法不应该发生这种情况,onSomethingHappened
因为只有系统调用它们。
- 如果您
MyActivity
再次扩展,您必须再次调用super
或再次使用相同的技巧。
一个非常相似的方法应该通过注释工作。例如, Android Annotations#HowItWorks是在编译时通过 Java 的注解处理器动态创建子类的示例。
例如,您可以编写代码,例如
class MySpecialActivity extends Activity {
@OnCreate
protected void randomlyNamed(Bundle savedInstanceState) {
// done.
}
}
注释处理器会生成
class MySpecialActivity_ extends MySpecialActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
randomlyNamed(savedInstanceState);
}
}
这里的缺点:
- 您需要编写相当复杂的代码来
.java
动态生成文件。
- 您需要配置构建环境以运行注释处理器。
- 您需要在多个地方使用该生成的子类而不是您的类。
- 你甚至没有保存一行代码,因为你用一些
@OnCreate
注释替换了超级调用。
更进一步,您可以通过修改编译的字节码(参见例如ASM)将超级调用物理地插入方法中。您仍然需要配置您的构建环境来执行该步骤,但现在您可以真正执行您在“更好”案例中编写的内容。像往常一样编写代码,如果你忘记了这些讨厌的调用,你的后编译器只会添加它们。
这也是proguard所做的。它检查字节码,在 Android 的 dex 编译器将结果转换为 android 的 dex 格式之前对其进行优化和混淆。