web-dev-qa-db-de.com

Android - onAttach (Context) nicht für API 23 aufgerufen

Ich habe das SDK auf die neueste Version (API 23) aktualisiert, und die onAttach(Activity)-Methode für fragment ist veraltet. Anstatt diese Methode zu verwenden, verwende ich jetzt onAttach(Context), aber diese wird nicht während des Lebenszyklus aufgerufen. Die Aktivität ist eine Instanz von AppCompatActivity aus v7 und das Fragment ist eine Instanz der Klasse Fragment (Android.app.Fragment).

Irgendwelche Ideen, wie man die onAttach in API 23 zum Laufen bringt?

Lösung

Ich habe einige Antworten gefunden, die Ihnen helfen können, dieses Problem zu verstehen und zu beheben: 

  • Wie bereits erwähnt, verwende ich die Aktivität von support v7 (AppCompatActivity) und das Fragment von Android.app. 

  • Zum Anzeigen von Fragmenten bekomme ich den Fragmentmanager mit der Methode getFragmentManager für die Aktivität, so dass der Fragmentmanager eine Instanz von FragmentManager aus Android.app ist -> und hier ist das Problem

  • Wenn Sie die Anwendung auf einem Gerät mit API 23 ausführen (ich habe es auf dem AS-Emulator ausgeführt), werden Sie feststellen, dass die onAttach (Context) -Methode aufgerufen wird. Während des Prozesses zum Anzeigen eines Fragments durch FragmentManager wird zu einem bestimmten Zeitpunkt die Methode onAttach (..) aufgerufen. Mit dem getFragmentManager () erhalten Sie eine Instanz des Fragmentmanagers, die für die Android-Version verfügbar ist, die auf diesem Gerät ausgeführt wird (z. B. API 22, 23). Wenn die Anwendung auf einem Gerät mit API <23 ausgeführt wird, ist die onAttach (Context) -Methode nicht verfügbar. Der Fragmentmanager weiß nicht, dass es in API 23 eine Methode onAttach (Context) gibt. Deshalb wird sie nicht aufgerufen Für die API <23 -> ist die Lösung für diese Art von Problemen die Verwendung des FragmentManagers aus Support-Bibliotheken. 

  • Lösungen: 

    1. Wenn Sie getSupportFragmentManager () verwenden, müssen Sie ein Fragment aus der Support-Bibliothek verwenden. Die erste Lösung besteht also darin, alle Fragmente durch das Fragment aus der Support-Lib zu ersetzen und getSupportFragmentManager () zu verwenden.

    2. Eine bereits implementierte Lösung besteht in der Handhabung von 2 Möglichkeiten (1. Die App läuft auf einem Gerät mit API <23, die App läuft auf einem Gerät mit API> = 23).

    Kurz gesagt, ich habe in meiner Implementierung eine Basisklasse für alle Fragmente aus dem Projekt und ich habe diesen Code dort hinzugefügt:

    /*
     * onAttach(Context) is not called on pre API 23 versions of Android and onAttach(Activity) is deprecated
     * Use onAttachToContext instead
     */
    @TargetApi(23)
    @Override
    public final void onAttach(Context context) {
        super.onAttach(context);
        onAttachToContext(context);
    }
    
    /*
     * Deprecated on API 23
     * Use onAttachToContext instead
     */
    @SuppressWarnings("deprecation")
    @Override
    public final void onAttach(Activity activity) {
        super.onAttach(activity);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            onAttachToContext(activity);
        }
    }
    
    /*
     * Called when the fragment attaches to the context
     */
    protected void onAttachToContext(Context context) {
    }
    

    Jetzt überschreibe ich einfach die onAttachToContext (Context) -Methode in allen Fragmenten, in denen ich diese benötige. 

    69
    David Rauca

    Ich habe das Problem auf diese Weise gelöst:

    @TargetApi(23)
    @Override public void onAttach(Context context) {
        //This method avoid to call super.onAttach(context) if I'm not using api 23 or more
        //if (Build.VERSION.SDK_INT >= 23) {
            super.onAttach(context);
            onAttachToContext(context);
        //}
    }
    
    /*
     * Deprecated on API 23
     * Use onAttachToContext instead
     */
    @SuppressWarnings("deprecation")
    @Override public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (Build.VERSION.SDK_INT < 23) {
            onAttachToContext(activity);
        }
    }
    
    /*
     * This method will be called from one of the two previous method
     */
    protected void onAttachToContext(Context context) {}
    
    26

    Sie sollten die Support-Bibliotheksversion von Fragment verwenden.

    Sie müssen zu import Android.support.v4.app.Fragment; anstelle von import Android.app.Fragment; wechseln. Sie müssen auch sicherstellen, dass Sie getSupportFragmentManager() anstelle von getFragmentManager() verwenden.

    17

    Ich bin auf dasselbe Problem gekommen. Ich habe eine minSdkVersion von 19 und eine targetSdkVersion von 23 und verwende fragmentManager in einer AppCompatActivity.

    onAttach(Activity activity) ist als veraltet markiert, aber ich bin auf App-Abstürze gestoßen, als ich es durch onAttach(Context context) ersetzt habe .

    Stattdessen habe ich jetzt beide Versionen vorhanden und wenn ich meine App auf API22 ausführe, onAttach(Activity activity)wird ausgelöst, obwohl sie als veraltet markiert ist.

    Ich habe es nicht auf einem Android Marshmallow-Gerät getestet, aber ich verstehe, dass es die onAttach(Context context) -Version ausführen würde, wobei die andere ignoriert wird.

    pdate um @ skaars Beobachtung in den Kommentaren unten zu berücksichtigen: Ich konnte jetzt auf API23 testen und kann bestätigen, dass das Laufen auf Plattform 23 beide Methoden verursacht (mit Activity und Kontext) aufgerufen werden. Danke für die Warnung!

    4
    0x4e84

    bitte posten Sie diesen Fehler hier 

    AUSGABE BEIM GOOGLE AOSP PROJECT HOMESITE GEÖFFNET:

    https://code.google.com/p/Android/issues/detail?id=185465

    ps. Dies ist nicht Ihre Aufgabe, nach einer Lösung für dieses Problem zu suchen und eine Art von Problemumgehung zu finden. Um dies zu tun, müssen Sie sich beschweren, wie ich gesagt habe.

    verwandtes Problem - getContext () aus Fragment:

    https://code.google.com/p/Android/issues/detail?id=185848

    4
    ceph3us

    Nachdem ich Ihre Antwort gelesen habe, @David Rauca Ich denke, der zweite kann mein Problem lösen. Aber wenn ich in den Quellcode schaue. Ich habe festgestellt, dass onAttach(Context context) auf Android M nichts tut, nur die alte Methode genannt.

    Als Lösung:

    @SuppressWarnings("deprecation")
    

    Fügen Sie es einfach der alten Methode hinzu, ist die beste Lösung.

    3
    Tony Zhang

    Ich bin auf das gleiche Problem gestoßen ... Was habe ich getan, um es zu lösen:

    1. Ändern Sie den Argumenttyp von onAttach-Rückruf von Activity in Context . Aus unbekannten Gründen führt diese Änderung dazu, dass die Methode onAttach (Context) nicht aufgerufen wird mehr während des Fragment-Lebenszyklus. Als Folge davon stürzte meine App ab, da der Code in der Methode onAttach Noch nie ausgeführt wurde. 

    2. Verschieben Sie den Code, der sich in der Methode onAttach befunden hat, seit OnCreate wird immer noch ausgeführt.

    Mit dieser Änderung funktioniert die App wie zuvor. Es wurden keine zusätzlichen import-Anweisungen benötigt.

    2
    Andrew
    @Override
    public void onAttach(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            super.onAttach(context);
            onAttachToContext(context);
        } else {
            Activity activity = getActivity();
            super.onAttach(activity);
            onAttachToContext(activity);
        }
    }
    
    0
    Name Surname