0

元の質問全体は間違いに基づいていました。final static FIELDコンストラクターで定数の値を割り当てることはできません。可能であれば、クラスの新しいインスタンスが作成されるたびに静的FIELDの値を変更できます。あまり最終的ではありません!

代わりに、これまで行ってきたことを実行できます(メモリリークが発生する可能性があるため、学ぶことがたくさんあります)。これは、static(ではなくfinal)フィールドを使用して、アクティビティの最新のインスタンスを指すことです(以下のコードサンプルを参照してください)。 )。メモリリークについての以下のコメントが指摘しているように、私はほぼ確実に、古い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);
    }
}

明らかに、TVと呼ばれるテキストビューを備えた簡単なlayout.xmlが必要です。権限は必要ありません。Androidを回転させて、画面が回転するたびにコンストラクターとonCreateの両方が再実行されることを示すアプリが再作成されるのを確認することもできますが、アクティビティが再作成されるときに静的な割り当ては再作成されません。

4

3 に答える 3

3

基本的に質問タイトルの主要部分に答えるには...

アクティビティでプライベートコンストラクタを使用してもよろしいですか...?

いいえ。

以前のJavaの観点からAndroidにアクセスしていると思いますが、Androidについて理解しておくべきことの1つは、このActivityクラスは、設計どおりに機能するように残しておく必要がある数少ない特殊なケースのクラスの1つであるということです。

クラスに関しては、コンストラクターの概念に関心を持たないでくださいActivity。適切に機能する設計方法論とアプリケーションの基本に従うだけです。

Androidフレームワーク内で機能しない特定の要件がある場合は、サンプルコードを使用して質問を投稿すると、誰かがそれを修正する方法を説明します。

編集:あなたの質問へのあなたの更新に照らして...

public final static MyActivity uI;

これが適切な場所にあると、呼び出しのチェーンを介して参照を渡すことなく、「ユーザーインターフェイス」オブジェクトをMyActivity.uIとして参照し直すことができます。

真剣に...そうしないでください。あなたがやろうとしている方法でモデルを「壊す」ことなく、最小限のコードでどんな状況でも簡単に処理するために使用できる完全に適切で機能的で安全なメカニズムがあります。

私が最初の答えで上で言ったことを繰り返すために-AndroidActivityクラスは特別な場合です。のインスタンスActivityとそのメソッド/フィールドは、他の外部クラスから直接アクセスされることを意図したものではありません。

Androidフレームワークの基本を受け入れるだけで、自分に有利に働き、多くの頭痛の種を減らすことができます。AndroidアプリのコーディングにはJavaが関係している可能性がありますが、すべての「一般的な」Javaの概念が、特になどのコアコンポーネントの一部に適用されるわけではありませんActivity

于 2012-04-14T18:51:53.933 に答える
2

アクティビティマネージャーがAcitivityをインスタンス化するため、コンストラクターが呼び出されない可能性があります。これがプライベートコンストラクター+finalで機能するかどうかはわかりません。

onCreateまた、(SharedPreferencesのように)呼び出されるまでアクティビティが完全に初期化されないため、構築時に使用できないものがいくつかあります。

于 2012-04-14T18:28:03.563 に答える
0

コンストラクターが呼び出される可能性があります。ただし、「単一の」アクティビティはありません(実際にはそうではありません)。したがって、アクティビティのインスタンスを参照するfinal変数を設定することは、これを実行する正しい方法ではありません。たとえば、向きの変更をサポートしている場合、アクティビティは(あなたが知っているように)再作成され、最終的な参照は間違っています。また、破棄されたアクティビティ(使用されなくなった)への参照があるため、そのアクティビティをリークしただけです。ビューを作成してインスタンス化する通常の方法を実行する必要があると思います。

とにかく、私はより良い質問は、すでに行われていることを回避しようとするのではなく、あなたが達成しようとしていること(そしてなぜそれがとても面倒だと思ったのか)の例だと思います。

于 2012-04-15T23:00:21.667 に答える