我最近在想应该如何更好地完成它
这是 Android SDK 默认使用的示例
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
这有点烦人,我们必须手动调用 super.onCreate
否则应用程序将抛出异常
有没有什么办法,如何通过注释或某种 AOP 钩子(Hook)更好地应用它?
我想要
public class MyActivity extends Activity {
@Override
@OnCreate // Replaces super.onCreate call
protected void onCreate(Bundle savedInstanceState) {
}
}
甚至更好
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
}
}
这可能吗?
最佳答案
如果您想专门删除一些 super.theMethodIAmIn()
调用,实际上,如果您在类中执行这些 super 调用,则可以与“甚至更好”的情况非常相似您扩展:
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
注解替换了 super 调用。
更进一步,您可以通过修改编译的字节码将 super 调用物理插入到方法中(例如,参见 ASM )。您仍然需要配置构建环境来执行该步骤,但现在您可以真正执行您在“甚至更好”的情况下编写的操作。像往常一样编写代码,如果您忘记了那些讨厌的调用,您的后编译器只会添加它们。
这也是 proguard 所做的事情。它会检查字节码,在 Android 的 dex 编译器将结果转换为 Android 的 dex 格式之前对其进行优化和混淆。
关于java - Android AOP/IOC 应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17792750/