3

Я пытаюсь выяснить, почему мое приложение для Android иногда срабатывает, с указанным выше исключением. Я не могу найти источник проблемы из того, что говорит logcat.IllegalStateException: Не удается выполнить это действие после того, как onSaveInstanceState - Andorid

Это случается редко. Я был бы рад за любое предложение. Благодаря!

выход

Logcat:

java.lang.IllegalStateException: Не удается выполнить это действие после onSaveInstanceState на android.support.v4.app.FragmentManagerImpl.checkStateLoss (FragmentManager.java:1360) в android.support.v4.app.FragmentManagerImpl.enqueueAction (FragmentManager.java:1378) на android.support.v4.app.BackStackRecord.commitInternal (BackStackRecord.java:595) на android.support.v4.app. BackStackRecord.commit (BackStackRecord.java:574)на android.support.v4.app.FragmentTabHost.onAttachedToWindow (FragmentTabHost.java:282) в android.view.View.dispatchAttachedToWindow (View.java:12752) при android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java : 2577) на android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:2584) на android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:2584) на android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup. java: 2584) на android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1427) на android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1192) на android.view.Vi ewRootImpl $ TraversalRunnable.run (ViewRootImpl.java:6231) на android.view.Choreographer $ CallbackRecord.run (Choreographer.java:788) в android.view.Choreographer.doCallbacks (Choreographer.java:591) в андроида (Хореограф.java:560) на android.view.Choreographer $ FrameDisplayEventReceiver.run (Хореограф.java:774) на android.os.Handler.handleCallback (Handler.java:808) на android .os.Handler.dispatchMessage (Handler.java:103) на android.os.Looper.loop (Looper.java:193) на android.app.ActivityThread.main (ActivityThread.java:5292) на java.lang .reflect.Method.invokeNative (собственный метод) в java.lang.reflect.Method.invoke (Method.java:515) на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:824) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:640) на dalvik.system.NativeStart.main (Native Method)

Основная деятельность:

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; 
    } 

} 
+0

Возможный дубликат [получение исключения] IllegalStateException: не удается выполнить это действие после onSaveInstanceState "] (http://stackoverflow.com/questions/7469082/getting-exception-illegalstateexception-can-not-perform-this-action- after-onsa) – JeanLuc

+0

Использовать .commitAllowingStateLoss() вместо Commit() при использовании фрагментов. –

+0

Я занимался некоторыми исследованиями, читал другие сообщения и блог-постер @Alex Lockwood по этой теме. Но у меня есть только Fragment TabHost в моей деятельности, и я никогда не называю «commit()». Обычно я получаю эту ошибку сразу после очередного сбоя, если в моем приложении есть. –

ответ

1

я испытывал подобную проблему на KitKat. Но на Lollipop это работает нормально. Независимо от того, мы должны поддерживать многие версии ОС, не так ли? :)

Основная причина, по-видимому, в том, что запуск нового действия заставляет MainActivity приостановить работу до того, как он будет полностью закончен. Когда он приостанавливается, он сохраняет состояние экземпляра сразу. Но так как Fragment экземпляры совершаются в странном цикле конца основного потока, цикл запуска-паузы-сохранения становится неуправляемым, бросая этот крах. И в некоторых случаях это может быть состояние гонки и случаться спорадически.

Вот код, который, кажется, чтобы исправить это после повторного тестирования:

@Override 
protected void onPostCreate(Bundle savedInstanceState) { 
    super.onPostCreate(savedInstanceState); 

    Handler hanlder = new Handler(); 
    hanlder.post(new Runnable() { 
     @Override 
     public void run() { 
      if (isFacebookLoggedIn()) { 
       System.out.println("We are logged in!"); 
      } else { 
       showLogin(); 
      } 

      if (datasource.getAllImageItems().isEmpty()) { 
       Intent splash = new Intent(MainActivity.this, SplashActivity.class); 
       startActivity(splash); 
      } 
     } 
    }); 
} 

Хитрость заключается в том, чтобы породить Handler и пост до конца основного потока, чтобы гарантировать, что это произойдет после того, как все Fragment экземпляры были совершено. Сделать это в onPostCreate, а не сразу в onCreate, также должно помочь.