web-dev-qa-db-ja.com

AndroidフラグメントonAttach()は非推奨

最新のサポートライブラリ(バージョン23.0.0)を使用するようにアプリを更新しました。FragmentクラスのonAttach()関数が廃止されたことがわかりました。

の代わりに:

onAttach (Activity activity)

雪が降る:

onAttach (Context context)

私のアプリは廃止予定の前に渡されたアクティビティを使用しているので、考えられる解決策は次のとおりです。

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    activity = getActivity();
}

それが正しい方法でしょうか。

更新:

私は23未満のAPIでデバイスを実行した場合、新しいonAttach()も呼び出されていません。これが彼らの意図したものではないことを願っています!

更新2:

SDKの最新のアップデートで問題は解決しました。

私は自分のAPI 22デバイス上でテストし、onAttach(Context)が呼ばれています。

ここ をクリックして、数週間前に公開したバグレポートと、Googleの人々からの回答をフォローします。

306
TareK Khoury

アクティビティはコンテキストなので、コンテキストがアクティビティであることを確認し、必要に応じてキャストすることができます。

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity a;

    if (context instanceof Activity){
        a=(Activity) context;
    }

}

更新: 新しいContextのオーバーライドは決して呼び出されないと主張する人もいます。私はいくつかのテストを行ったが、これが真実であるというシナリオを見つけることができず、そしてソースコードによれば、それは決して真実であるべきではない。私がテストしたすべてのケースで、SDK23の前後両方、ActivityContextの両方のバージョンのonAttachが呼び出されました。そうでないシナリオを見つけることができれば、私はあなたが問題を説明するサンプルプロジェクトを作成し、 それをAndroidチームに報告することをお勧めします

アップデート2: バグが早く修正されるため、Android Support Libraryのフラグメントのみを使用します。オーバーライドが正しく呼び出されないという上記の問題は、フレームワークフラグメントを使用した場合にのみ明らかになります。

319
Kuffs

これはグーグルからのもう一つの大きな変化です...提案された修正:onAttach(Activity activity)onAttach(Context context)で置き換えることはonAttach(Context context)がネイティブフラグメントで呼ばれないので古いAPI上の私のアプリをクラッシュさせました。

私はネイティブのフラグメント(Android.app.Fragment)を使用しているので、古いAPI(<23)でそれが再び機能するようにするために次のことをしなければなりませんでした。

これが私がしたことです:

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    // Code here
}

@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        // Code here
    }
}
42
Yoann Hercouet

フレームワークフラグメントを使用していて、デバイスのSDKバージョンが23より低い場合、OnAttach(Context context)は呼び出されません。

代わりにサポートフラグメントを使用しているので、非推奨は修正され、onAttach(Context context)が常に呼び出されます。

38
kikermo

現在、onAttachフラグメントコードから、Contextが現在のアクティビティであるかどうかは明確ではありません。ソースコード

public void onAttach(Context context) {
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) {
        mCalled = false;
        onAttach(hostActivity);
    }
}

getActivityを見ると、同じ呼び出しが表示されます

/**
 * Return the Activity this fragment is currently associated with.
 */
final public Activity getActivity() {
    return mHost == null ? null : mHost.getActivity();
}

アクティビティを取得していることを確認したい場合は、getActivity()onAttach内のFragment内)を使用しますが、nullを確認することを忘れないでください。 mHostnullです_あなたのアクティビティはnull

11
royB
@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity activity = context instanceof Activity ? (Activity) context : null;
}
6
worked

ほとんどの場合、onAttach(Context)を持つことで十分であるように思えますが、それが呼ばれていないところにいくつかの電話(すなわち、Xiaomi Redme Note 2)があります、従ってそれはNullPointerExceptionsを引き起こします。そのため、安全のために、非推奨のメソッドもそのまま使用することをお勧めします。

// onAttach(Activity) is necessary in some Xiaomi phones
@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    _onAttach(activity);
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    _onAttach(context);
}

private void _onAttach(Context context) {
    // do your real stuff here
}
3
Gavriel

Sdkマネージャで最新のサポートライブラリをダウンロードしてください。

compile 'com.Android.support:appcompat-v7:23.1.1'

gradle.appで、コンパイルバージョンをapi 23に設定します。

3
Essah

あなたはおそらくAndroid.support.v4.app.Fragmentを使っています。これにはonAttachメソッドの代わりに、フラグメントが関連付けられているFragmentActivityを取得するためにgetActivity()を使用します。そうでなければonAttach(Context context)メソッドを使うことができます。

1
LeoCoder

以下の答えは、Android開発者WebサイトのFragmentsチュートリアルで発生するこの非推奨警告に関連しており、上記の投稿に関連していない可能性があります。

私はチュートリアルの授業でこのコードを使いましたが、うまくいきました。

public void onAttach(Context context){
    super.onAttach(context);

    Activity activity = getActivity();

ドキュメンテーションに記載されているように、アクティビティがnullになる可能性があることを心配していました。

getActivity

FragmentActivity getActivity()このフラグメントが現在関連付けられているFragmentActivityを返します。フラグメントが代わりにContextに関連付けられている場合はnullを返す場合があります。

しかし、main_activityのonCreateは、フラグメントがロードされたことを明確に示しているため、このメソッドの後で、フラグメントからget activityを呼び出すとmain_activityクラスが返されます。

getSupportFragmentManager()。beginTransaction().add(R.id.fragment_container、firstFragment).commit();

私はこれが正しいことを願っています。私は絶対に初心者です。

1
Roy Selim