0

我最近在考虑应该如何以更好的方式完成

这是默认使用 Android SDK 的示例

public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

}

这有点烦人,我们必须手动调用,super.onCreate否则应用程序会抛出异常

有什么方法可以更好地应用它,带有注释或某种 AOP 钩子?

我想拥有

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) {

    }

}

这可能吗?

4

1 回答 1

1

如果您想专门摆脱某些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 格式之前对其进行优化和混淆。

于 2013-07-22T19:34:14.697 回答