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?

0voto

CoolMind Punkte 21914

In meinem Fall wurden die Fragmentmethoden nach

getActivity().onBackPressed();

0voto

Raz Punkte 448

Ein alter Beitrag, aber ich war überrascht über die am meisten hochgestimmte Antwort.

Die richtige Lösung hierfür sollte sein, die Asynctask in onStop (oder an einer anderen geeigneten Stelle in Ihrem Fragment) abzubrechen. Auf diese Weise führen Sie kein Speicherleck ein (eine Asynctask behält einen Verweis auf Ihr zerstörtes Fragment) und Sie haben eine bessere Kontrolle darüber, was in Ihrem Fragment vor sich geht.

@Override
public void onStop() {
    super.onStop();
    mYourAsyncTask.cancel(true);
}

0voto

Jose Punkte 21

Fügen Sie dies zu Ihrem Fragemnt hinzu

Activity activity;
@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    activity = context instanceof Activity ? (Activity) context : null;
}

Dann ändern getContext() , getActivity() , requireActivity() oder requireContext() mit Tätigkeit

-1voto

Einfache Lösung und 100%ige Wirkung

if (getActivity() == null || !isAdded()) return;

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