为什么按设置活动工具栏上的向上按钮会破坏以前的活动?

时间:2018-10-09 12:35:08

标签: java android android-activity android-lifecycle onresume

目标:当用户在SettingsActivity工具栏上按回时,应从用户离开的位置恢复上一个活动。

问题:从android开发者网站上报告的Activity生命周期中,我了解应该恢复先前的Activity并调用OnResume方法,而在我的情况下,MainActivity会再次调用OnCreate方法。

具体流程如下:

1)用户单击图标以启动SettingsActivity

2)MapsActivity依次调用onPause,然后依次onSaveInstanceStateonStop

3)用户单击SettingsActivity上的后退按钮

4)MapsActivity先调用onDestroy,然后再onCreate(由于在saveInstanceState始终为空的情况下,我在第2点用Bundle试图保存的所有内容都丢失了)

代码

MapsActivity(主要活动)

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

SettingsActivity(称为活动)

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>

问题::如何恢复以前的“活动”状态,并向用户准确显示他打开第二个“活动”时的可视化状态?

编辑#1: 我试图覆盖o onDestroy()onSaveInstance()onRestoreInstance(),这是发生的情况:

  • 当我开始设置活动时,主要活动如预期般进行onPause()

  • 当我在settings活动上按“后退”按钮时,主要活动进入onDestroy()之前和之后onCreate()之后,而不是在onSaveInstance()onRestoreInstance()处调用全部。

编辑#2:该应用未通过onSaveInstanceState(Bundle outState),可能是因为我宣布它为公开。现在,应用程序将其调用。因此,我尝试保存一些信息,例如outState.putBoolean("prova", true);,但是当mainActivity被销毁时,在新的onCreate(Bundle savedInstanceState)调用下,Bundle savedInstanceState始终为null。

编辑#3:,因为@SherifelKhatib建议我尝试从finish()删除所有MapsActivity语句,并尝试用最小的{替换MapsActivity {1}},看看问题是否出在EmptyActivity中。不幸的是,该应用程序具有相同的行为。 当用户按下“后退”按钮时,先前的应用程序将始终被销毁。无法恢复其状态。

编辑#4:我尝试过但仍无法正常工作。修改MapsActivity

第一种方法

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

1 个答案:

答案 0 :(得分:0)

解决方案:

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

android:launchMode="singleTop"

说明

  

“标准”和“单顶”模式的不同之处仅在于   一个方面:每当有新的意图提出“ 标准”   活动中,创建了该类的新实例来对此进行响应   意图。每个实例都处理一个意图。同样,新   还可以创建“ singleTop ”活动的实例来处理新   意图。但是,如果目标任务已经有一个现有实例   活动在其堆栈的顶部,该实例将收到   新的意图(在onNewIntent()调用中); 新实例不是   已创建