1

Meine MainActivity lädt verschiedene Fragmente. Darüber hinaus kann eine Settings-Aktivität von der MainActivity aus geöffnet werden.OnResume/OnPause mehrfach aufgerufen

Wenn der Benutzer nur zwischen Fragmenten wechselt, ist alles in Ordnung.

Beim Öffnen der Einstellungen-Aktivität und Zurückgehen zu MainActivity werden onResume und onPause zweimal aufgerufen. Wenn der Benutzer Einstellungen-Aktivität öffnet und wieder zu MainActivity zurückkehrt, werden onResume und onPause dreimal aufgerufen. Dies wird jedes Mal größer, wenn der Benutzer die Einstellungen-Aktivität öffnet und zu MainActivity zurückkehrt.

MainActivity

public class MainActivity extends AppCompatActivity implements MyFragment.OnListFragmentInteractionListener, AsyncResponse { 


        private FragmentA fragmentA = new FragmentA(); 

        private DatabaseHandler databaseHandler = new DatabaseHandler(this); 

        private NavigationView navigationView; 
        private DrawerLayout drawer; 
        private Toolbar toolbar; 

        // index to identify current nav menu item 
        private static int navItemIndex = 0; 

        public static String CURRENT_TAG = MyConstants.TAG_FRAGMENT_A; 

        // toolbar titles respected to selected nav menu item 
        private String[] activityTitles; 

        // flag to load home fragment when user presses back key 
        private Handler mHandler; 

        @Override 
        protected void onCreate(Bundle savedInstanceState) { 

         super.onCreate(savedInstanceState); 

         setContentView(R.layout.activity_main); 

         fragmentA.setDatabaseHandler(this.databaseHandler); 

         // Init UI 
         toolbar = (Toolbar) findViewById(R.id.toolbar); 
         setSupportActionBar(toolbar); 

         mHandler = new Handler(); 

         drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
         navigationView = (NavigationView) findViewById(R.id.nav_view); 

         fabSendButton = (FloatingActionButton) findViewById(R.id.fab); 

         // Navigation view header 
         navHeader = navigationView.getHeaderView(0); 


         // load toolbar titles from string resources 
         activityTitles = getResources().getStringArray(R.array.sliding_menu_item_activity_titles); 


         // initializing navigation menu 
         setUpNavigationView(); 

         if (savedInstanceState == null) { 
          navItemIndex = 0; 
          CURRENT_TAG = MyConstants.TAG_FRAGMENT_A; 
          loadHomeFragment(); 
         } 
        } 

        /*** 
        * Returns respected fragment that user 
        * selected from navigation menu 
        */ 
        private void loadHomeFragment() { 

         // set toolbar title 
         setToolbarTitle(); 

         // if user select the current navigation menu again, don't do anything 
         // just close the navigation drawer 
         if (getSupportFragmentManager().findFragmentByTag(CURRENT_TAG) != null) { 
          drawer.closeDrawers(); 
          return; 
         } 

         // Sometimes, when fragment has huge data, screen seems hanging 
         // when switching between navigation menus 
         // So using runnable, the fragment is loaded with cross fade effect 
         // This effect can be seen in GMail app 
         Runnable mPendingRunnable = new Runnable() { 
          @Override 
          public void run() { 
           // update the activity_main_header_with_item content by replacing fragments 
           Fragment fragment = getFragment(); 
           FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
           fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out); 
           fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG); 
           fragmentTransaction.commit(); 
          } 
         }; 

         // If mPendingRunnable is not null, then add to the message queue 
         if (mPendingRunnable != null) { 
          mHandler.post(mPendingRunnable); 
         } 

         //Closing drawer on item click 
         drawer.closeDrawers(); 

         // refresh toolbar menu 
         invalidateOptionsMenu(); 
        } 

        private Fragment getFragment() { 
         switch (navItemIndex) { 
          case 0: 
           return this.fragmentA; 
          case 1: 
           Fragment B fragmentB = new FragmentB(); 
           fragmentB.setDatabaseHandler(this.databaseHandler); 
           return fragmentB; 
          default: 
           return this.fragmentA; 
         } 
        } 

        private void setToolbarTitle() { 
         getSupportActionBar().setTitle(activityTitles[navItemIndex]); 
        } 

        private void setUpNavigationView() { 
         //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu 
         navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { 

          // This method will trigger on item Click of navigation menu 
          @Override 
          public boolean onNavigationItemSelected(MenuItem menuItem) { 

           //Check to see which item was being clicked and perform appropriate action 
           switch (menuItem.getItemId()) { 
            //Replacing the activity_main_header_with_item content with ContentFragment Which is our Inbox View; 
            case R.id.nav_A: 
             navItemIndex = 0; 
             CURRENT_TAG = MyConstants.TAG_FRAGMENT_A; 
             break; 
            case R.id.nav_B: 
             navItemIndex = 1; 
             CURRENT_TAG = MyConstants.TAG_FRAGMENT_B; 
             break; 
            default: 
             navItemIndex = 0; 
           } 

           loadHomeFragment(); 

           return true; 
          } 
         }); 

         ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.openDrawer, R.string.closeDrawer) { 

          @Override 
          public void onDrawerClosed(View drawerView) { 
           // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank 
           super.onDrawerClosed(drawerView); 
          } 

          @Override 
          public void onDrawerOpened(View drawerView) { 
           // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank 
           super.onDrawerOpened(drawerView); 
          } 
         }; 

         //Setting the actionbarToggle to drawer layout 
         drawer.setDrawerListener(actionBarDrawerToggle); 

         //calling sync state is necessary or else your hamburger icon wont show up 
         actionBarDrawerToggle.syncState(); 
        } 

        @Override 
        public boolean onCreateOptionsMenu(Menu menu) { 
         getMenuInflater().inflate(R.menu.activity_main_header_with_item, menu); 
         return true; 
        } 

      @Override 
       public boolean onCreateOptionsMenu(Menu menu) { 
        getMenuInflater().inflate(R.menu.activity_main_header_with_item, menu); 
        // Disable Player Icon in case no player is found on device 
        Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, ScrobblOrDroidConstants.MUSIC_APP); 
        List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0); 
        if(activities == null || activities.size() <= 0) { 
         MenuItem player = menu.findItem(R.id.player); 
         if(player != null){ 
          player.setVisible(false); 
         } 
        } 
        return true; 
       } 

       @Override 
       public boolean onOptionsItemSelected(MenuItem item) { 
        // Handle action bar item clicks here. The action bar will 
        // automatically handle clicks on the Home/Up button, so long 
        // as you specify a parent activity in AndroidManifest.xml. 
        int id = item.getItemId(); 

        //noinspection SimplifiableIfStatement 
        if (id == R.id.player) { 
         Timber.i("Added onClick listener to ImageView ivPlayer."); 
         Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, ScrobblOrDroidConstants.MUSIC_APP); 
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
         startActivity(intent); 
         return true; 
         } else if (id == R.id.settings) { 
         // launch settings activity 
         startActivity(new Intent(MainActivity.this, SettingsActivity.class)); 
         return true; 
        } 
        return super.onOptionsItemSelected(item); 
       } 

      @Override 
      public void onResume() { 
       Timber.i("MainActivity.onResume-called."); 
       activityVisible = true; 
       updateHomeFragment(); 
       callLongUserOperation(); 
       super.onResume(); 
      } 

      @Override 
      public void onPause() { 
       Timber.i("MainActivity.onPause-called."); 
       activityVisible = false; 
       super.onPause(); 
      } 
     } 

    public void updateHomeFragment() { 
     if (CURRENT_TAG == MyConstants.TAG_HOME) { 
      Timber.i("updating HomeFragment"); 
      fragmentA.swap(); 
     } 
    } 

SettingsActivity

public class SettingsActivity extends AppCompatPreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setupActionBar(); 
     getFragmentManager().beginTransaction().replace(android.R.id.content, new MainPreferenceFragment()).commit(); 
    } 

    private void setupActionBar() { 
     ViewGroup rootView = (ViewGroup)findViewById(R.id.action_bar_root); 
     View view = getLayoutInflater().inflate(R.layout.pref_toolbar, rootView, false); 
     rootView.addView(view, 0); 
     Toolbar toolbar = (Toolbar)findViewById(R.id.pref_toolbar); 
     setSupportActionBar(toolbar); 
     ActionBar actionBar = getSupportActionBar(); 
     if (actionBar != null) { 
      // Show the Up button in the action bar. 
      actionBar.setDisplayHomeAsUpEnabled(true); 
     } 
    } 

    public static class MainPreferenceFragment extends PreferenceFragment { 
     @Override 
     public void onCreate(final Bundle savedInstanceState) { 

      super.onCreate(savedInstanceState); 
      addPreferencesFromResource(R.xml.pref_main); 

      // gallery EditText change listener 
      bindPreferenceSummaryToValue(findPreference(MyConstants.RECENTLY_SCROBBLED_KEY)); 

      bindPreferenceSummaryToValue(findPreference(MyConstants.SCROBBLE_DURATION_KEY)); 

      // feedback preference click listener 
      Preference myPref = findPreference("key_send_feedback"); 
      myPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 
       public boolean onPreferenceClick(Preference preference) { 
        sendFeedback(getActivity()); 
        return true; 
       } 
      }); 

      // rating preference click listener 
      Preference myPrefRate = findPreference("key_send_rate"); 
      myPrefRate.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 
       public boolean onPreferenceClick(Preference preference) { 
        sendRating(getActivity()); 
        return true; 
       } 
      }); 
     } 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     if (item.getItemId() == android.R.id.home) { 
      onBackPressed(); 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    private static void bindPreferenceSummaryToValue(Preference preference) { 
     preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); 
     sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, 
       PreferenceManager.getDefaultSharedPreferences(preference.getContext()).getString(preference.getKey(), "")); 
    } 

    /** 
    * A preference value change listener that updates the preference's summary 
    * to reflect its new value. 
    */ 
    private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { 
     @Override 
     public boolean onPreferenceChange(Preference preference, Object newValue) { 
      String stringValue = newValue.toString(); 

      if(preference.getKey().equalsIgnoreCase(MyConstants.RECENTLY_SCROBBLED_KEY)){ 
       preference.setSummary(stringValue + " " + preference.getContext().getResources().getString(R.string.pref_recently_scrobbled_summary)); 
      } 
      if(preference.getKey().equalsIgnoreCase(MyConstants.SCROBBLE_DURATION_KEY)){ 
       preference.setSummary(preference.getContext().getResources().getString(R.string.pref_scrobble_percentage_summary, stringValue)); 
      } 
      return true; 
     } 
    }; 

    /** 
    * Email client intent to send support mail 
    * Appends the necessary device information to email body 
    * useful when providing support 
    */ 
    public static void sendFeedback(Context context) { 
     String body = null; 
     try { 
      body = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName; 
      body = "\n\n-----------------------------\nPlease don't remove this information\n Device OS: Android \n Device OS version: " + 
        Build.VERSION.RELEASE + "\n App Version: " + body + "\n Device Brand: " + Build.BRAND + 
        "\n Device Model: " + Build.MODEL + "\n Device Manufacturer: " + Build.MANUFACTURER; 
     } catch (PackageManager.NameNotFoundException e) { 
     } 
     Intent intent = new Intent(Intent.ACTION_SEND); 
     intent.setType("message/rfc822"); 
     intent.putExtra(Intent.EXTRA_EMAIL, new String[]{MyConstants.E_MAIL_ADDRESS}); 
     intent.putExtra(Intent.EXTRA_SUBJECT, "Feedback for " + context.getResources().getString(R.string.app_name)); 
     intent.putExtra(Intent.EXTRA_TEXT, body); 
     context.startActivity(Intent.createChooser(intent, context.getString(R.string.pref_choose_email_client))); 
    } 

    public static void sendRating(Context context) { 
     Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(MyConstants.PLAY_STORE_URL)); 
     context.startActivity(i);; 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).registerOnSharedPreferenceChangeListener(this); 
    } 

    @Override 
    public void onPause() { 
     PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).registerOnSharedPreferenceChangeListener(this); 
     super.onPause(); 
    } 

    @Override 
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 
     if(key.equalsIgnoreCase(MyConstants.NOTIFICATION_ENABLED_KEY)){ 
      EventBus.getDefault().post(new NotificationEvent()); 
      Timber.i("NotificationEvent Posted"); 
     } 
    } 
} 

AppCompatPreferenceActivity

public class AppCompatPreferenceActivity extends PreferenceActivity { 

     private AppCompatDelegate mDelegate; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      getDelegate().installViewFactory(); 
      getDelegate().onCreate(savedInstanceState); 
      super.onCreate(savedInstanceState); 
     } 

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

     public ActionBar getSupportActionBar() { 
      return getDelegate().getSupportActionBar(); 
     } 

     public void setSupportActionBar(@Nullable Toolbar toolbar) { 
      getDelegate().setSupportActionBar(toolbar); 
     } 

     @Override 
     public MenuInflater getMenuInflater() { 
      return getDelegate().getMenuInflater(); 
     } 

     @Override 
     public void setContentView(@LayoutRes int layoutResID) { 
      getDelegate().setContentView(layoutResID); 
     } 

     @Override 
     public void setContentView(View view) { 
      getDelegate().setContentView(view); 
     } 

     @Override 
     public void setContentView(View view, ViewGroup.LayoutParams params) { 
      getDelegate().setContentView(view, params); 
     } 

     @Override 
     public void addContentView(View view, ViewGroup.LayoutParams params) { 
      getDelegate().addContentView(view, params); 
     } 

     @Override 
     protected void onPostResume() { 
      super.onPostResume(); 
      getDelegate().onPostResume(); 
     } 

     @Override 
     protected void onTitleChanged(CharSequence title, int color) { 
      super.onTitleChanged(title, color); 
      getDelegate().setTitle(title); 
     } 

     @Override 
     public void onConfigurationChanged(Configuration newConfig) { 
      super.onConfigurationChanged(newConfig); 
      getDelegate().onConfigurationChanged(newConfig); 
     } 

     @Override 
     protected void onStop() { 
      super.onStop(); 
      getDelegate().onStop(); 
     } 

     @Override 
     protected void onDestroy() { 
      super.onDestroy(); 
      getDelegate().onDestroy(); 
     } 

     public void invalidateOptionsMenu() { 
      getDelegate().invalidateOptionsMenu(); 
     } 

     private AppCompatDelegate getDelegate() { 
      if (mDelegate == null) { 
       mDelegate = AppCompatDelegate.create(this, null); 
      } 
      return mDelegate; 
     } 
    } 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.ordroid.My" 
    android:versionCode="1" 
    android:versionName="1.0"> 

    <uses-sdk 
     android:minSdkVersion="15" 
     android:targetSdkVersion="25" /> 

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme"> 
     <activity 
      android:name=".ui.activity.MainActivity" 
      android:label="@string/app_name" 
      android:screenOrientation="portrait"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity 
      android:name=".ui.activity.LoginActivity" 
      android:excludeFromRecents="true" 
      android:label="@string/app_name" 
      android:screenOrientation="portrait"></activity> 
     <activity 
      android:name=".ui.activity.SettingsActivity" 
      android:label="@string/settings"> 
      <!-- Parent activity meta-data to support 4.0 and lower --> 
      <meta-data 
       android:name="android.support.PARENT_ACTIVITY" 
       android:value=".ui.activity.MainActivity" /> 
     </activity> 

     <!-- start service on device boot complete --> 
     <receiver 
      android:name=".util.receiver.MyBroadcastReceiver" 
      android:enabled="true" 
      android:exported="true" 
      android:label="StartMyServiceAtBootReceiver"> 
      <intent-filter> 
       <action android:name="com.android.music.metachanged" /> 
       <action android:name="com.android.music.playstatechanged" /> 
       <!-- <action android:name="android.intent.action._BOOT_COMPLETED" /> --> 
      </intent-filter> 
     </receiver> 
     <receiver android:name=".util.receiver.MyInternetConnectionBroadcastReceiver"> 
      <intent-filter> 
       <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 
      </intent-filter> 
     </receiver> 

    </application> 

</manifest> 

Wie kann ich vermeiden, dass diese mehrere Anrufe?

+0

Versuchen Sie, addPreferencesFromResource nur aufzurufen, wenn savedInstanceState null ist? – stkent

+1

können Sie den Teil Ihres Manifests hinzufügen, der mit diesen Aktivitäten in Zusammenhang steht? es könnte uns eine bessere Idee geben – Jon

+0

Manifest hinzugefügt! – joshi737

Antwort

1

Scheint, es war ein Fehler im Android SDK Build Tool. Nach dem Update funktioniert es wie ein Charme!

+0

Ich habe das gleiche Problem mit onCreate onResume onPause mehrmals aufrufen. Hast du das wirklich behoben? – yozhik

0

Ich sah das gleiche Problem, wo onResume() einer meiner Aktivitäten dreimal aufgerufen wurde.

Ich habe es behoben, indem ich einen Boolean in onCreate() der entsprechenden Aktivität als false gesetzt habe. Zum Beispiel:

boolean onResumeCalled = false 

und jedes Mal, wenn die Aktivität erstellt wird, halte ich onResumeCalled als falsch.

In onResume(), habe ich einen Scheck

if(!onResumeCalled) 

in Beginn onResume().

Jetzt, wenn die Aktivität erstellt wird, ist onResumeCalled false. Sobald ich die Methoden in onResume() aufgerufen habe, ändere ich den Wert von onResumeCalled in true, so dass beim zweiten Aufruf von onResume() nicht auf die Methoden in onResume() zugegriffen wird, da der Wert von onResumeCalled jetzt ist wahr.

Verwandte Themen