java - Android AOP/IOC 应用

标签 java android inversion-of-control aop

我最近在想应该如何更好地完成它

这是 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/

相关文章:

android - Toast 上的事件已隐藏

android - Android中自定义圆形复选框

asp.net-mvc - ASP.NET MVC ContactsManager 教程中是否有解决依赖注入(inject)循环问题的好/正确方法?

java - java中如何从字符串中读取并提取整数

java - Java 中可接受的避免多重继承缺失的方法

java - 如何使用stripe-java或rest api获取产品的计划

java - 如何从对话框内的edittext获取文本

c# - 单元测试依赖注入(inject)

generics - CaSTLe Windsor Ioc 解析 web.config 中的通用类

Java Swing JButton