Почему предыдущая активность уничтожается нажатием кнопки вверх на панели инструментов настройки активности? - PullRequest
0 голосов
/ 09 октября 2018

ЦЕЛЬ: когда пользователь снова нажимает на панели инструментов SettingsActivity, предыдущее действие должно быть возобновлено с того места, где он ушел.

ПРОБЛЕМА: Из жизненного цикла Activity, представленной на веб-сайте разработчика Android, я понимаю, что предыдущую активность следует возобновить, вызвав метод OnResume, вместо этого в моем случае MainActivity снова начнет вызывать OnCreate method.

В частности, процесс выглядит следующим образом:

1) Пользователь нажимает на иконку, чтобы начать SettingsActivity

2) MapsActivity вызывает onPause,затем onSaveInstanceState, затем onStop

3) Пользователь нажимает кнопку "Назад" на SettingsActivity

4) MapsActivity вызывает onDestroy, затем onCreate (и все, что я пыталсясохранение в точке 2 с saveInstanceState потеряно, потому что 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);
        }
    }

Настройки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>

ВОПРОС: как я могу восстановить предыдущее состояние «Активность» и показать пользователю именно то, что он визуализировал, когда открыл второй Acti?Vity?

РЕДАКТИРОВАТЬ # 1: Я попытался переопределить o onDestroy(), onSaveInstance(), onRestoreInstance(), и вот что происходит:

  • когда я начинаю задание по настройке, основное занятие идет onPause(), как и следовало ожидать.

  • Когда я нажимаю кнопку "Назад" на задании по настройке, основное действие выполняется до onDestroy() и сразу после onCreate(), вообще не вызывая onSaveInstance() или onRestoreInstance().

РЕДАКТИРОВАТЬ # 2: приложение не прошло onSaveInstanceState(Bundle outState), вероятно, потому что я объявил его публичным.Теперь приложение вызывает это.Поэтому я попытался сохранить некоторую информацию, такую ​​как outState.putBoolean("prova", true);, но когда mainActivity уничтожена, при новом вызове onCreate(Bundle savedInstanceState) Bundle savedInstanceState всегда равен нулю.

РЕДАКТИРОВАТЬ # 3: , поскольку @SherifelKhatib предложил, чтобы я попытался удалить все операторы finish() из MapsActivity, и я попытался заменить 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);

1 Ответ

0 голосов
/ 13 октября 2018

РЕШЕНИЕ:

Добавьте этот атрибут к MainActivity в манифесте.

android:launchMode="singleTop"

Пояснение

Режимы "standard" и "singleTop" отличаются друг от друга только в одном отношении: каждый раз, когда появляется новое намерение для стандарта "" "активность, новый экземпляр класса создан для ответа на это намерение.Каждый экземпляр обрабатывает одно намерение.Аналогично, новый экземпляр действия « singleTop » также может быть создан для обработки нового намерения.Однако, если целевая задача уже имеет существующий экземпляр действия на вершине своего стека, этот экземпляр получит новое намерение (в вызове onNewIntent ()); новый экземпляр не создан .

...