Ich habe eine kleine Test-App erstellt, die mein Problem darstellt. Ich verwende ActionBarSherlock, um Tabs mit (Sherlock) Fragmenten zu implementieren.Fragment MyFragment nicht an Aktivität angefügt
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 hinzugefügt, um die Thread.sleep
Teil das Herunterladen von Daten zu simulieren. Der Code in onPostExecute
soll die Verwendung des Fragment
simulieren.
Wenn ich den Bildschirm sehr schnell zwischen Quer- und Hochformat drehen, erhalte ich eine Ausnahme bei dem onPostExecute
Code:
java.lang.IllegalStateException: Fragment MyFragment {410f6060} nicht an Aktivität
Ich denke es ist, weil eine neue MyFragment
in der Zwischenzeit erstellt wurde, und wurde an die Aktivität vor der AsyncTask
abgeschlossen. Der Code in onPostExecute
ruft eine nicht verbundene MyFragment
.
Aber wie kann ich das beheben?
Du solltest View from Fragment inflater verwenden. 'mView = inflater.inflate (R.layout.my_layout, container, false)' Und jetzt benutze diese Ansicht, wenn du Ressourcen bekommen willst: 'mView.getResources(). ***'. Es hilft mir, diesen Fehler zu beheben. – foxis
@foxis Das leckt den 'Context', der an Ihre' mView' angehängt ist. – nhaarman
Vielleicht überprüfe ich es noch nicht. Um Leck zu vermeiden, wie um Null 'mView' in onDestroy zu erhalten? – foxis