Android Fragment onAttach()は廃止予定


326

最新のサポートライブラリ(バージョン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のみんなからの回答に従うこと。


渡されたインスタンスから特定のアクティビティメソッドを使用している場合、コンテキストをアクティビティにキャストしてみましたか?ActivityはContextのサブクラスであることを思い出してください。多分キャスティングがうまくいくでしょう。
MarkSkayff 2015

何らかの理由で、onAttach()が呼び出されていません!何か案は?最新のサポートlibに更新してみましたか?
TareK Khoury

2
なぜAPIはに移動したのContextですか?Activityとにかくフラグメントを添付して表示するためには必要ありませんか?他にどのようにContextパラメーターを使用しますか?
ケニーワーデン、2015

1
バグとして投稿しました。リンクcode.google.com/p/android/issues/detail?id=183358を
TareK Khoury

6
new onAttach(Context context)を呼び出すには、少なくともAPI 23を備えたデバイスを使用するか、android.support.v4.app.Fragmentを使用する必要があります。こちらをご覧ください
nevzo

回答:


337

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

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

    Activity a;

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

}

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

更新2:バグが早く修正されるため、Androidサポートライブラリのフラグメントのみを使用します。オーバーライドが正しく呼び出されない上記の問題は、フレームワークフラグメントを使用した場合にのみ明らかになります。


5
onAttach with contextはonAttach with activityと同じ方法で呼び出されないため、実際にはソリューションではありません。パラメータとしてアクティビティを持つonAttachに初期化コードがある場合、この変更は機能しません。
バディ

2
いいえ、少なくとも私の場合、同じようには動作しません。onAttachではアクティビティもコンテキストも使用せず、初期化を行います。onAttachをアクティビティのあるものに置き換えてみましたが、同じように呼び出されません。そのため、それらは簡単に交換することはできません。
バディ

7
バディが持っているのと同じ問題が... onAttach(Context)呼び出されるようにも見えません。
ステファン・

2
コードをステップ実行しましたが、onAttach(context)が呼び出されない可能性があることを確認できました。
チャドビンガム2015

2
私の場合、以前にシステムによってクリアされたアクティビティを再開すると、onAttach()は呼び出されません。しかし、常にそうであるとは限りません。WeakReferenceの初期化をonAttach(Context context)に入れました。refActivity= new WeakReference <>((AppCompatActivity)context)です。また、onCreateView()でNullPointerExceptionが時々スローされます。
Kimi Chiu

45

これはGoogleからのもう1つの大きな変更です...提案された変更:ネイティブフラグメントで呼び出されないため、古いAPI onAttach(Activity activity)onAttach(Context context)クラッシュした私のアプリに置き換えますonAttach(Context context)

私はネイティブフラグメント(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
    }
}

Mr.Yoann Hercouet、API 23の上でそれを行う方法を説明できます。事前に感謝します。E/ AndroidRuntime:FATAL EXCEPTION:main、java.lang.ClassCastException:com.ual.SMS_Activity@afd5683、android。 support.v4.app.FragmentManagerImpl.moveToState、android.support.v4.app.FragmentManagerImpl.execSingleActionで。ここに私はあなたが私のバグを知るために必要な行を投稿しました。
MohanRaj S 2016

@MohanRajSこれはAPI 24(私が使用したもの)でも同じです。コードによれば、問題はこれで何もする必要がないようです。
Yoann Hercouet

@YoannHercouet、返信ありがとうございます。確認と更新をさせてください。
MohanRaj S 2016

1
古いAPIをターゲットにするのが難しいため、これについてGoogleに不満があります。まあ、古いAPIをターゲットにできるという祝福を考えてみてください。たとえば、Appleは、あなたを途方もなく無力にして、最新のものだけをサポートするように強制します。
スタン

39

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

代わりにサポートフラグメントを使用しているため、廃止予定は修正され、onAttach(Context context)常に呼び出されます。


11

現在、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


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

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

5

ほとんどの場合はで十分のようですが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

SDKマネージャーを含む最新のサポートライブラリをダウンロードし、

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

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


1

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

チュートリアルレッスンでこのコードを使用しましたが、うまくいきました。

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

    Activity activity = getActivity();

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

getActivity

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

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

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

私はこれで正しいと思います。私はまったくの初心者です。


1

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


0

これは私がユーザー定義のインターフェイス「TopSectionListener」、そのオブジェクトアクティビティコマンダーを持っているときに私のために働きました:

  //This method gets called whenever we attach fragment to the activity
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    Activity a=getActivity();
    try {
        if(context instanceof Activity)
           this.activitycommander=(TopSectionListener)a;
    }catch (ClassCastException e){
        throw new ClassCastException(a.toString());}

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.