可以在Activity中使用私有构造函数,所以我可以在变量上使用final修饰符?

时间:2012-04-14 18:18:38

标签: java android android-activity

整个原始问题是基于一个错误。您永远不能在构造函数中指定final static FIELD常量的值。如果可以的话,每次创建类的新实例时,您将拥有静态FIELD 更改的值。不是最终决定!

我可以改为做我一直在做的事情(并且可能会造成内存泄漏,我还有很多需要学习的东西),即使用static(但不是final)字段来指向我的Activity的最新实例(请参阅下面的代码示例)。正如下面关于内存泄漏的讨论指出的那样,我几乎肯定是通过保持对旧的Activity对象的引用来创建内存泄漏。

所以我原来问题的答案实际上归结为:这不是一件好事,因为将其他对象引用交给我当前的Activity对象可以让它们不再垃圾收集旧的Activity对象!

无论如何,这里是我原来问题中提到的代码,答案和评论仍然在这里,所以剩下的内容是为了参考那些。

public class MyActivity extends Activity {
  public final static MyActivity uI;
  public static MyActivity mostRecentUI;

  private MyActivity() { // this is the constructor
      // In my original post I had:
      // uI = this;  
      // but this is illegal code.  `final static anything;` cannot be assigned a 
      // value in the constructor, because it could be assigned a different value
      // each time the class is instantiated!  

      // Instead the best I can do is
      mostRecentUIobject = this;
      // and this name better describes what this static variable contains
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
  }
}

添加4/15:@dmon甚至评论构造函数不会运行。任何有疑问的人都可以参加这项测试活动:

public class TestActivityConstructor extends Activity {
    static long refTime = System.currentTimeMillis();
    static String staticExecution = "Static never executed\n";
    static String constructorExecution = "Constructor never executed\n";
    static String onCreateExecution = "onCreate never executed\n";

    static {
        staticExecution = "Static Execution at " + (System.currentTimeMillis() - refTime) + " ms\n";
    }

    public TestActivityConstructor() {
        constructorExecution = "Constructor Execution at " + (System.currentTimeMillis() - refTime) + "ms \n";
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        onCreateExecution = "onCreate Execution at " + (System.currentTimeMillis() - refTime) + "ms \n";
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ((TextView) findViewById(R.id.TV)).setText(staticExecution + constructorExecution + onCreateExecution);
    }
}

显然,你需要一个简单的layout.xml和一个名为TV的textview。无需权限。您甚至可以通过旋转Android来看到重新创建的应用程序,显示每次旋转屏幕时都会重新运行构造函数和onCreate,但在重新创建Activity时不会重做静态赋值。

3 个答案:

答案 0 :(得分:3)

基本上回答问题标题的主要部分......

  

可以在Activity中使用私有构造函数吗??

没有

我假设你是从以前的Java站点来到Android,但要了解Android的一件事是Activity类是少数特殊案例类之一应该留待工作因为他们的目的是为了。

当涉及到Activity类时,不要关注构造函数的概念,只需遵循设计方法和应用程序基础,这些工作原理非常适用。

如果您有特定要求在Android框架内无效,请发布带有示例代码的问题,有人会解释如何修复它。

编辑:根据您对问题的更新...

public final static MyActivity uI;
  

有了这个,我可以将“用户界面”对象称为MyActivity.uI,而不必通过调用链传递引用。

说真的......不要那样做。有完全适当的,功能性的和安全的机制,可以用最简单的代码轻松处理任何情况,而不会像你试图做的那样“打破”模型。

重复上面我在原始答案中所说的内容 - Android Activity类是一个特例。 Activity及其方法/字段的实例不应由任何其他外部类直接访问。

如果您只是接受Android框架的基础知识,那么您将帮自己一个忙,并且可以避免很多麻烦。编写Android应用程序可能涉及Java,但并非所有“通用”Java概念都适用,特别是某些核心组件,例如Activity

答案 1 :(得分:2)

由于活动管理器实现了您的Acitivity,您可能无法调用构造函数 - 不确定它是否适用于私有构造函数+ final。

由于您的活动在调用onCreate之前未完全初始化(如SharedPreferences),因此在构建时无法使用多项内容。

答案 2 :(得分:0)

很好,你的构造函数可能会被调用。但是,没有“单一”活动(不是真的),因此设置引用活动实例的最终变量并不是正确的方法。例如,如果您支持方向更改,则会重新创建活动(如您所知),并且您的最终引用是错误的。此外,由于您引用了已销毁的活动(不再使用),您刚刚泄露了该活动。我担心你将不得不通过创建和实例化视图的常规方法。

无论如何,我认为一个更好的问题是你想要完成的一个例子(以及为什么你发现它如此麻烦),而不是试图支持已经存在的东西。