I am trying to figure out why my android app crashes sometimes, with the above exception. I can't find the source of the problem from what the logcat says.
It happens rarely.
Logcat output:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1360) at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1378) at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595) at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574) at android.support.v4.app.FragmentTabHost.onAttachedToWindow(FragmentTabHost.java:282) at android.view.View.dispatchAttachedToWindow(View.java:12752) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2577) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2584) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2584) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2584) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1427) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1192) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6231) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788) at android.view.Choreographer.doCallbacks(Choreographer.java:591) at android.view.Choreographer.doFrame(Choreographer.java:560) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5292) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640) at dalvik.system.NativeStart.main(Native Method)
Main Activity:
public class MainActivity extends FragmentActivity {
private FragmentTabHost mTabHost;
private UiLifecycleHelper uiHelper;
LocationClient mClient;
LocationRequest mRequest;
private String user;
private String userId;
private ImageButton addPlaceBtn;
private SQLiteDataSource datasource;
private TextView notifTextView;
private boolean appIsOn = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
setContentView(R.layout.activity_main);
datasource = new SQLiteDataSource(this);
datasource.open();
uiHelper = new UiLifecycleHelper(this, null);
uiHelper.onCreate(savedInstanceState);
if (isFacebookLoggedIn()) {
System.out.println("We are logged in!");
} else {
showLogin();
}
if (datasource.getAllImageItems().isEmpty()) {
Intent splash = new Intent(this, SplashActivity.class);
startActivity(splash);
}
addPlaceBtn = (ImageButton) findViewById(R.id.addPlace1);
uiHelper = new UiLifecycleHelper(this, null);
uiHelper.onCreate(savedInstanceState);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(),
android.R.id.tabcontent);
mTabHost.addTab(
mTabHost.newTabSpec("tab1").setIndicator("PREPARATE", null),
OffersFragmentActivity.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("tab2").setIndicator("CATEGORII", null),
CategoriesActivity.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab3")
.setIndicator("CAIETE", null), BooksFragmentActivity.class,
null);
for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); i++) {
mTabHost.getTabWidget().getChildAt(i)
.setBackgroundResource(R.drawable.tab_text_selector);
mTabHost.getTabWidget().setDividerDrawable(R.drawable.divider);
final TextView tv = (TextView) mTabHost.getTabWidget()
.getChildAt(i).findViewById(android.R.id.title);
if (tv == null)
continue;
else
tv.setTextColor(0xFFFFFFFF);
}
mTabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
switch (mTabHost.getCurrentTab()) {
case 0:
addPlaceBtn.setVisibility(View.VISIBLE);
break;
case 1:
addPlaceBtn.setVisibility(View.GONE);
break;
case 2:
addPlaceBtn.setVisibility(View.GONE);
break;
default:
break;
}
}
});
addPlaceBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (user != null && isOnline()) {
Intent i = new Intent(getApplication(),
CameraActivity.class);
startActivity(i);
} else if (user == null) {
// If user is not logged in, start login activity
Intent i = new Intent(getApplication(), LoginActivity.class);
startActivity(i);
} else if (!isOnline()) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
MainActivity.this);
alertDialogBuilder.setTitle("Internetul este oprit");
alertDialogBuilder
.setMessage("Pentru actualizarea continutului aveti nevoie de internet. Porniti acum?");
alertDialogBuilder.setPositiveButton("Da",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
// go to a new activity of the app
Intent settingsIntent = new Intent(
Settings.ACTION_DATA_ROAMING_SETTINGS);
settingsIntent
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(settingsIntent);
finish();
}
});
// set negative button: No message
alertDialogBuilder.setNegativeButton("Nu",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
// cancel the alert box and put a Toast to
// the user
finish();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
});
if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
final Menu m = menu;
final MenuItem item = menu.findItem(R.id.action_notifications);
View actionView = item.getActionView();
notifTextView = (TextView) actionView.findViewById(R.id.notifTextView);
String unreadNotifs = datasource.countUnreadNotif();
if (!unreadNotifs.equals("0")) {
notifTextView.setText(unreadNotifs);
} else {
notifTextView.setVisibility(View.GONE);
}
item.getActionView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
m.performIdentifierAction(item.getItemId(), 0);
}
});
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_user) {
Intent i = new Intent(this, UserProfile.class);
i.putExtra("user", user);
i.putExtra("userId", userId);
startActivity(i);
return true;
}
if (id == R.id.action_notifications) {
Intent i = new Intent(this, Notifications.class);
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
private boolean isFacebookLoggedIn() {
Session session = Session.getActiveSession();
if (session != null) {
// Session can be open, check for valid token
if (!session.isClosed()) {
if (!session.getAccessToken().equalsIgnoreCase("")) {
return true;
}
}
}
return false;
}
// FB Login Session and user info
public void showLogin() {
Intent i = new Intent(this, LoginActivity.class);
startActivity(i);
}
@Override
protected void onResume() {
super.onResume();
uiHelper.onResume();
appIsOn = true;
invalidateOptionsMenu();
if (!isOnline()) {
showGpsButton();
}
SharedPreferences preferences = getSharedPreferences("USERINFO",
Context.MODE_PRIVATE);
user = preferences.getString("name", null);
userId = preferences.getString("userId", null);
userId = preferences.getString("userId", null);
GCMActivity gcm = new GCMActivity(this);
gcm.registerIfNeeded();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
@Override
public void onPause() {
super.onPause();
uiHelper.onPause();
appIsOn = false;
}
@Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
datasource.deleteAllRows();
}
public void showGpsButton() {
LinearLayout buttonLayout = (LinearLayout) findViewById(R.id.gpsWarning);
buttonLayout.setVisibility(View.VISIBLE);
buttonLayout.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent settingsIntent = new Intent(
Settings.ACTION_DATA_ROAMING_SETTINGS);
settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(settingsIntent);
finish();
}
});
}
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
return true;
}
return false;
}
}
commit()
, the framework certainly is. The proof is in the stack trace:android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
(BackStackRecord
is the framework's internal implementation of the abstractFragmentTransaction
class). – Alex Lockwood