429 Stimmen

Fragment MyFragment nicht mit Aktivität verbunden

Ich habe eine kleine Testanwendung erstellt, die mein Problem darstellt. Ich verwende ActionBarSherlock, um Registerkarten mit (Sherlock)-Fragmenten zu implementieren.

Mein Code: TestActivity.java

public class TestActivity extends SherlockFragmentActivity {
    private ActionBar actionBar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupTabs(savedInstanceState);
    }

    private void setupTabs(Bundle savedInstanceState) {
        actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        addTab1();
        addTab2();
    }

    private void addTab1() {
        Tab tab1 = actionBar.newTab();
        tab1.setTag("1");
        String tabText = "1";
        tab1.setText(tabText);
        tab1.setTabListener(new TabListener<MyFragment>(TestActivity.this, "1", MyFragment.class));

        actionBar.addTab(tab1);
    }

    private void addTab2() {
        Tab tab1 = actionBar.newTab();
        tab1.setTag("2");
        String tabText = "2";
        tab1.setText(tabText);
        tab1.setTabListener(new TabListener<MyFragment>(TestActivity.this, "2", MyFragment.class));

        actionBar.addTab(tab1);
    }
}

TabListener.java

public class TabListener<T extends SherlockFragment> implements com.actionbarsherlock.app.ActionBar.TabListener {
    private final SherlockFragmentActivity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    /* The following are each of the ActionBar.TabListener callbacks */

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);

        // Check if the fragment is already initialized
        if (preInitializedFragment == null) {
            // If not, instantiate and add it to the activity
            SherlockFragment mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            ft.attach(preInitializedFragment);
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);

        if (preInitializedFragment != null) {
            // Detach the fragment, because another one is being attached
            ft.detach(preInitializedFragment);
        }
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}

MyFragment.java

public class MyFragment extends SherlockFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException ex) {
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void result){
                getResources().getString(R.string.app_name);
            }

        }.execute();
    }
}

Ich habe die Thread.sleep Teil, um das Herunterladen von Daten zu simulieren. Der Code im Teil onPostExecute ist die Simulation der Nutzung des Fragment .

Wenn ich den Bildschirm sehr schnell zwischen Hoch- und Querformat drehe, erhalte ich eine Exception bei der onPostExecute Code:

java.lang.IllegalStateException: Fragment MyFragment mit Aktivität verbunden

Ich glaube, das liegt daran, dass eine neue MyFragment wurde in der Zwischenzeit erstellt und wurde der Aktivität vor der AsyncTask beendet. Der Code in onPostExecute ruft einen ungebundenen MyFragment .

Aber wie kann ich das beheben?

15voto

superUser Punkte 1012
if (getActivity() == null) return;

funktioniert auch in einigen Fällen. Unterbricht einfach die Codeausführung und stellt sicher, dass die App nicht abstürzt

10voto

Aristo Michael Punkte 2138

Ich konfrontiert das gleiche Problem, das ich fügen Sie einfach die singletone Instanz zu erhalten Ressource wie von Erick verwiesen

MainFragmentActivity.defaultInstance().getResources().getString(R.string.app_name);

können Sie auch verwenden

getActivity().getResources().getString(R.string.app_name);

Ich hoffe, dies wird Ihnen helfen.

2voto

Marcell Punkte 609

Ähnliche Probleme traten bei mir auf, als die Aktivität Anwendungseinstellungen mit den geladenen Einstellungen sichtbar war. Wenn ich eine der Einstellungen änderte und dann den Anzeigeinhalt drehte und die Einstellung erneut änderte, stürzte die Anwendung mit der Meldung ab, dass das Fragment (meine Klasse "Einstellungen") nicht mit einer Aktivität verbunden war.

Bei der Fehlersuche sah es so aus, als ob die onCreate()-Methode des PreferencesFragments zweimal aufgerufen wurde, wenn der Anzeigeinhalt gedreht wurde. Das war schon seltsam genug. Dann fügte ich die isAdded()-Prüfung außerhalb des Blocks hinzu, wo sie den Absturz anzeigen würde, und das Problem war gelöst.

Hier ist der Code des Listeners, der die Zusammenfassung der Einstellungen aktualisiert, um den neuen Eintrag anzuzeigen. Er befindet sich in der onCreate()-Methode meiner Preferences-Klasse, die die PreferenceFragment-Klasse erweitert:

public static class Preferences extends PreferenceFragment {
    SharedPreferences.OnSharedPreferenceChangeListener listener;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // ...
        listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
                // check if the fragment has been added to the activity yet (necessary to avoid crashes)
                if (isAdded()) {
                    // for the preferences of type "list" set the summary to be the entry of the selected item
                    if (key.equals(getString(R.string.pref_fileviewer_textsize))) {
                        ListPreference listPref = (ListPreference) findPreference(key);
                        listPref.setSummary("Display file content with a text size of " + listPref.getEntry());
                    } else if (key.equals(getString(R.string.pref_fileviewer_segmentsize))) {
                        ListPreference listPref = (ListPreference) findPreference(key);
                        listPref.setSummary("Show " + listPref.getEntry() + " bytes of a file at once");
                    }
                }
            }
        };
        // ...
    }

Ich hoffe, dies wird anderen helfen!

1voto

Anthony Chuinard Punkte 1018

Wenn Sie die Application und ein statisches "globales" Kontextobjekt wie folgt pflegen, dann können Sie dieses anstelle der Aktivität zum Laden einer String-Ressource verwenden.

public class MyApplication extends Application {
    public static Context GLOBAL_APP_CONTEXT;

    @Override
    public void onCreate() {
        super.onCreate();
        GLOBAL_APP_CONTEXT = this;
    }
}

Wenn Sie dies verwenden, können Sie mit folgenden Maßnahmen auskommen Toast und Ressourcenbelastung, ohne sich um Lebenszyklen zu kümmern.

1voto

Ich hatte eine ähnliche Fehlermeldung "Fragment MyFragment nicht mit Kontext verbunden" in Xamarine Android.

diese Fehlermeldung wird aufgrund des Aufrufs dieser Ressource angezeigt

button.Text = Resources.GetString(Resource.String.please_wait)

Ich habe das mit Xamarine Android behoben.

if (Context != null && IsAdded){ 
    button.Text = Resources.GetString(Resource.String.please_wait);
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X