it-swarm.com.de

Android Fragment onAttach () veraltet

Ich habe meine App auf die neueste Unterstützungsbibliothek (Version 23.0.0) aktualisiert und festgestellt, dass sie die Funktion onAttach () der Fragment-Klasse nicht mehr unterstützt.

Anstatt von:

onAttach (Activity activity)

Es schneit:

onAttach (Context context)

Da meine App die Aktivität verwendet, die vor dem Verfall übergeben wurde, ist eine mögliche Lösung:

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

Wäre das der richtige Weg?

UPDATE:

Wenn ich ein Gerät mit einer API unter 23 starte, wird das neue onAttach () nicht einmal aufgerufen. Ich hoffe, das ist nicht das, was sie vorhatten!

UPDATE 2:

Das Problem wurde mit den neuesten Updates für das SDK behoben.

Ich habe auf meinem API 22-Gerät getestet und onAttach (Context) wird aufgerufen.

Klicken Sie auf hier , um den Fehlerbericht, den ich vor ein paar Wochen geöffnet habe, und die Antworten der Jungs von Google zu verfolgen.

314
TareK Khoury

Aktivität ist ein Kontext. Wenn Sie also einfach überprüfen können, ob der Kontext eine Aktivität ist, können Sie ihn bei Bedarf umsetzen.

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

    Activity a;

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

}

Update: Einige behaupten, dass der neue Context Override niemals aufgerufen wird. Ich habe einige Tests durchgeführt und kann kein Szenario finden, in dem dies zutrifft. Entsprechend dem Quellcode sollte dies niemals zutrifft. In allen Fällen, die ich vor und nach SDK23 getestet habe, wurden sowohl die Activity- als auch die Context -Versionen von onAttach aufgerufen. Wenn Sie ein Szenario finden, in dem dies nicht der Fall ist, empfehlen wir Ihnen, ein Beispielprojekt zu erstellen, das das Problem veranschaulicht, und melden Sie es dem Android Team .

Update 2: Ich verwende immer nur die Android Support Library-Fragmente, da Fehler dort schneller behoben werden. Es scheint, dass das obige Problem, bei dem die Überschreibungen nicht korrekt aufgerufen werden, nur dann auftritt, wenn Sie die Framework-Fragmente verwenden.

324
Kuffs

Dies ist eine weitere großartige Änderung von Google ... Die vorgeschlagene Änderung: onAttach(Activity activity) durch onAttach(Context context) ersetzen hat meine Apps auf älteren APIs zum Absturz gebracht, da onAttach(Context context) nicht für native Fragmente aufgerufen wird.

Ich verwende die nativen Fragmente (Android.app.Fragment), daher musste ich Folgendes tun, damit es auf älteren APIs wieder funktioniert (<23).

Folgendes habe ich getan:

@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
    }
}
43
Yoann Hercouet

Wenn Sie die Framework-Fragmente verwenden und die SDK-Version des Geräts niedriger als 23 ist, wird OnAttach(Context context) nicht aufgerufen.

Ich verwende stattdessen Unterstützungsfragmente, so dass die Verfallserklärung behoben ist und onAttach(Context context) immer aufgerufen wird.

38
kikermo

Derzeit ist aus dem Fragmentcode onAttach nicht klar, ob Context die aktuelle Aktivität ist: Quellcode

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

Wenn Sie sich getActivity ansehen, wird derselbe Anruf angezeigt

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

Wenn Sie also sicherstellen möchten, dass Sie die Aktivität erhalten, verwenden Sie getActivity() (in onAttach in Ihrem Fragment), aber vergessen Sie nicht, nach null zu suchen, denn wenn mHost ist null Ihre Aktivität wird null sein

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

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

Obwohl es den Anschein hat, dass es in den meisten Fällen ausreicht, onAttach(Context) zu haben, gibt es einige Telefone (d. H .: Xiaomi Redme Note 2), auf denen kein Anruf erfolgt, sodass NullPointerExceptions ausgelöst werden. Um auf der sicheren Seite zu sein, schlage ich vor, die veraltete Methode ebenfalls zu verlassen:

// 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
}
4
Gavriel

Laden Sie die neueste Support-Bibliothek mit dem SDK-Manager herunter und fügen Sie sie hinzu

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

in gradle.app und setze compile version auf api 23

3
Essah

sie verwenden wahrscheinlich Android.support.v4.app.Fragment. Verwenden Sie dazu anstelle der Methode onAttach einfach getActivity(), um die FragmentActivity abzurufen, mit der das Fragment verknüpft ist. Andernfalls könnten Sie die Methode onAttach(Context context) verwenden.

1
LeoCoder

Die folgende Antwort bezieht sich auf diese Warnung zur Nichtbeachtung, die im Fragment-Lernprogramm auf der Entwickler-Website Android angezeigt wird, und möglicherweise nicht auf die oben genannten Posts.

Ich habe diesen Code in der Tutorial-Lektion verwendet und es hat funktioniert.

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

    Activity activity = getActivity();

Ich war besorgt, dass die Aktivität möglicherweise null ist, wie in der Dokumentation angegeben.

getActivity

FragmentActivity getActivity () Gibt die FragmentActivity zurück, mit der dieses Fragment derzeit verknüpft ist. Kann null zurückgeben, wenn das Fragment stattdessen einem Kontext zugeordnet ist.

Das onCreate on the main_activity zeigt jedoch deutlich, dass das Fragment geladen wurde. Nach dieser Methode gibt der Aufruf von get activity vom Fragment die main_activity-Klasse zurück.

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

Ich hoffe ich habe recht damit. Ich bin ein absoluter Neuling.

1
Roy Selim