58

私は最近、自分のを作成するときにString引数を渡すためのキーを常に知っている必要があることにうんざりしていました。そこで、設定したいパラメーターを受け取るコンストラクターを作成し、それらの変数を正しいキーでに配置することにしました。これにより、他のキーやそれらのキーを知る必要がなくなりました。BundlesFragmentsFragmentsBundlesStringFragmentsActivities

public ImageRotatorFragment() {
    super();
    Log.v(TAG, "ImageRotatorFragment()");
}

public ImageRotatorFragment(int imageResourceId) {
    Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");

    // Get arguments passed in, if any
    Bundle args = getArguments();
    if (args == null) {
        args = new Bundle();
    }
    // Add parameters to the argument bundle
    args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId);
    setArguments(args);
}

そして、私は通常のようにそれらの議論を引き出します。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v(TAG, "onCreate");

    // Set incoming parameters
    Bundle args = getArguments();
    if (args != null) {
        mImageResourceId = args.getInt(KEY_ARG_IMAGE_RES_ID, StaticData.getImageIds()[0]);
    }
    else {
        // Default image resource to the first image
        mImageResourceId = StaticData.getImageIds()[0];
    }
}

ただし、Lintはこれに問題を抱えておりFragment、他のパラメーターを持つコンストラクターのサブクラスを持たないため@SuppressLint("ValidFragment")、アプリの実行にも使用する必要がありました。問題は、このコードは完全に正常に機能するということです。ImageRotatorFragment(int imageResourceId)または古い学校の方法を使用して、手動でImageRotatorFragment()呼び出すことができます。setArguments()Androidがフラグメントを再作成する必要がある場合(方向の変更またはメモリ不足)、コンストラクターを呼び出してから、正しく設定された値を使用してImageRotatorFragment()同じ引数を渡します。Bundle

そのため、私は「推奨」アプローチを探していて、パラメーターを使用newInstance()して作成するために使用する多くの例を確認しました。これは、私のコンストラクターと同じことを行うようです。Fragmentsそれで私はそれをテストするために自分で作りました、そしてそれはそれについて泣き言を言うリントを除いて、以前と同じように完璧に動作します。

public static ImageRotatorFragment newInstance(int imageResourceId) {
    Log.v(TAG, "newInstance(int imageResourceId)");

    ImageRotatorFragment imageRotatorFragment = new ImageRotatorFragment();

    // Get arguments passed in, if any
    Bundle args = imageRotatorFragment.getArguments();
    if (args == null) {
        args = new Bundle();
    }
    // Add parameters to the argument bundle
    args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId);
    imageRotatorFragment.setArguments(args);

    return imageRotatorFragment;
}

newInstance()個人的には、コンストラクターの使用は、パラメーターの使用方法と受け渡しを知っているよりもはるかに一般的な方法であることがわかりました。これと同じコンストラクター手法をActivitiesで使用でき、Lintはそれについて文句を言うことはないと思います。だから基本的に私の質問は、なぜグーグルはあなたにパラメータを持つコンストラクタを使用させたくないのですFragmentsか?

私の唯一の推測は、を使用せずにインスタンス変数を設定しようとしないことです。Bundleこれは、が再作成されたときに設定されませんFragment。メソッドを使用することによりstatic newInstance()、コンパイラーはインスタンス変数にアクセスできなくなります。

public ImageRotatorFragment(int imageResourceId) {
    Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");

    mImageResourceId = imageResourceId;
}

コンストラクターでのパラメーターの使用を禁止するのに、これが十分な理由であるとはまだ感じていません。他の誰かがこれについて洞察を持っていますか?

4

2 に答える 2

64

個人的には、コンストラクターを使用する方が、newInstance()を使用してパラメーターを渡すことを知っているよりも、はるかに一般的な方法であることがわかりました。

ファクトリメソッドパターンは、最近のソフトウェア開発でかなり頻繁に使用されています。

だから基本的に私の質問は、なぜグーグルはあなたにフラグメントのパラメーターを持つコンストラクターを使用させたくないのですか?

あなたはあなた自身の質問に答えました:

私の唯一の推測は、バンドルを使用せずにインスタンス変数を設定しようとしないことです。バンドルは、フラグメントが再作成されたときに設定されません。

正しい。

コンストラクターでのパラメーターの使用を禁止するのに、これが十分な理由であるとはまだ感じていません。

ご意見をお待ちしております。コンストラクターごとまたはワークスペースごとの方法で、このLintチェックを無効にすることができます。

于 2013-02-01T21:03:17.430 に答える
2

Androidは、デフォルトのコンストラクターを使用して強制終了したフラグメントのみを再作成するため、追加のコンストラクターで行った初期化はすべて失われるため、データは失われます。

于 2016-07-08T11:38:20.450 に答える