为什么按设置 Activity 工具栏上的向上按钮会破坏前一个 Activity?

Why previous Activity get destroyed pressing up button on Setting Activity Toolbar?

目标: 当用户在 SettingsActivity 工具栏上按回键时,上一个 Activity 应该从用户离开的地方恢复。

问题: 来自 android 开发者网站上报告的 Activity 生命周期 我了解到之前的 Activity 应该恢复调用 OnResume 方法,而不是在我的例子中 MainActivity 再次开始调用 OnCreate 方法。

具体流程如下:

1) 用户点击图标开始SettingsActivity

2)MapsActivity 调用 onPause,然后调用 onSaveInstanceState,然后调用 onStop

3) 用户在 SettingsActivity

上单击后退按钮

4)MapsActivity 调用 onDestroy 然后 onCreate (我在第 2 点用 saveInstanceState 尝试保存的所有内容都丢失了,因为 Bundle 总是空)

代码

地图Activity(主要activity)

 @Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);

    // .... other initialization code ... //

    // If location permission is granted initialize Map
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

        mapSync();

    } else {


        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);

    }

}

@Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("prova", true);
    }


// Where I start the second activity
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
        case R.id.connection_type:
              // .... handle this case ... //
case R.id.settings:

                Intent intent = new Intent(MapsActivity.this, SettingsActivity.class);
                startActivity(intent);
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

设置Activity(调用activity)

public class SettingsActivity extends AppCompatActivity
{

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings);

        // Set the toolbar
        Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);

        myToolbar.setTitle("Settings");
        myToolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24px);
        myToolbar.setNavigationOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                finish();
            }
        });
        setSupportActionBar(myToolbar);



    }


    public  static class MainSettingsFragment extends PreferenceFragmentCompat {

        public final static String KEY_ENABLE_BACKGROUND_UPDATE = "enable_background_update";
        public final static String KEY_ENABLE_LAST_KNOWN_LOCATION = "enable_last_known_location";
        public final static String KEY_DELETE_DB_DATA = "delete_db_data";
        public final static String KEY_CHANGE_MAP_COLOR ="change_map_color";

        private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener;
        @Override
        public void onCreatePreferences(Bundle bundle, String s) {
            // Load the Preferences from the XML file
            addPreferencesFromResource(R.xml.preferences);

            preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
                @Override
                public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

                    if(key.equals(KEY_DELETE_DB_DATA))
                    {

                        String connectivityType = sharedPreferences.getString(key, null);
                        new DeleteAreaAsync(SignalAreaDatabase.getDatabase(getContext()), connectivityType).execute();

                    } else if(key.equals(KEY_CHANGE_MAP_COLOR)){

                        String gradientColor = sharedPreferences.getString(key, null);
                        SignalAreaDrawer signalAreaDrawer = SignalAreaDrawer.getSignalAreaDrawer();
                        signalAreaDrawer.setGradientColor( gradientColor);





                    }

                }
            };

        }

        @Override
        public void onResume() {
            super.onResume();
            getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(preferenceChangeListener);
        }

        @Override
        public void onPause() {
            super.onPause();
            getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
        }
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<!--
     The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
     Google Maps Android API v2, but you must specify either coarse or fine
     location permissions for the 'MyLocation' functionality. 
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Less accurate location: telephony manager and location requests -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Access to wifi network information -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Change wifi connectivity state -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar">

    <!--
         The API key for Google Maps-based APIs is defined as a string resource.
         (See the file "res/values/google_maps_api.xml").
         Note that the API key is linked to the encryption key used to sign the APK.
         You need a different API key for each encryption key, including the release key that is used to
         sign the APK for publishing.
         You can define the keys for the debug and release targets in src/debug/ and src/release/. 
    -->
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />

    <activity
        android:name=".MapsActivity"
        android:label="@string/title_activity_maps">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".SettingsActivity"
        android:parentActivityName=".MapsActivity"
        android:theme="@style/PreferenceScreen" />
</application>

问题: 我怎样才能恢复以前的 Activity 状态并向用户准确显示他在打开第二个 Activity 时看到的内容?

编辑#1: 我试图覆盖 oonDestroy() , onSaveInstance(), onRestoreInstance() ,结果是这样的:

编辑 #2: 应用程序未通过 onSaveInstanceState(Bundle outState) 可能是因为我声明了它 public。现在应用程序调用它。所以我试图保存一些信息,比如 outState.putBoolean("prova", true); 但是当 mainActivity 被销毁时,在新的 onCreate(Bundle savedInstanceState) 调用中 Bundle savedInstanceState 总是空的。

编辑 #3: 正如@SherifelKhatib 建议的那样,我尝试从 MapsActivity 中删除所有 finish() 语句,并尝试替换 MapsActivity 用最小的 EmptyActivity 来查看问题是否在 MapsActivity 中。不幸的是,该应用程序具有相同的行为。 当用户按下后退按钮时,之前的应用程序总是会被销毁。无法恢复其状态。

编辑 #4: 我试过但仍然无效。修改 SettingsActivity :

第一种方法

 @Override
    public void onBackPressed(){
        moveTaskToBack(true);
    }

第二种方法

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Respond to the action bar's Up/Home button
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

第三种方法

@Override
public void onBackPressed() {
    Intent backIntent = new Intent(this, MapsActivity.class);
    backIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    startActivity(backIntent);
}

并在 MainActivity 中添加:

 Intent intent = new Intent(MapsActivity.this, SettingsActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                startActivity(intent);

解决方案:

将此属性添加到清单中的 MainActivity

android:launchMode="singleTop"

说明

The "standard" and "singleTop" modes differ from each other in just one respect: Every time there's a new intent for a "standard" activity, a new instance of the class is created to respond to that intent. Each instance handles a single intent. Similarly, a new instance of a "singleTop" activity may also be created to handle a new intent. However, if the target task already has an existing instance of the activity at the top of its stack, that instance will receive the new intent (in an onNewIntent() call); a new instance is not created.