I understand that my question is very abstract, but I would rather describe it in words so that it is clear what is happening.

There is a mine activating it has a fragment. In the fragment there is an ArrayList variable. It is initialized to the OnCreate fragment. In the fragment's onStart method, it is initialized with a specific value and the fragment's ListView populated through the adapter.

Also there is SettingsActivivty it is empty; nothing is displayed in it yet.

So the problem is that when you click the Settings button in MainActivity , a transition to SettingsActivity occurs. And everything would be fine, but when you press the back key, we return to the lane to activate, and the fragment onCreate method is called again. and the ArrayList variable is reset again. And it was expected that the fragment's onResume method will be onResume .

But once the onCreate method is onCreate this means that the fragment has been destroyed. But why?

http://i.stack.imgur.com/NtPP8.jpg as we see in this image, if the activation closes another activation, then the onResume method is onResume , but not with me.

Please give me advice on what can be done, I can provide the necessary pieces of code if I simply need it, I do not know what I need to solve this issue. Main Main Activation Code package com.example.android.sunshine.app;

 import android.content.Intent; import android.os.Bundle; import android.os.PersistableBundle; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState == null) { //Если первый запуск активити // Создать новый контейтер getSupportFragmentManager().beginTransaction().add(R.id.container, new ForecastFragment(), "TAG").commit(); } else { // Или найти предыдуший созданный ForecastFragment fragment = (ForecastFragment) getSupportFragmentManager().findFragmentByTag("TAG"); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "TAG").commit(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); 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.action_settings) { Intent intent = new Intent(this, SettingsActivity.class); startActivityForResult(intent,1); return true; } return super.onOptionsItemSelected(item); } } 

Fragment code

 package com.example.android.sunshine.app; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; import android.view.*; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.util.ArrayList; public class ForecastFragment extends Fragment { public ForecastFragment() { } //ListView listView_forecast; private ArrayList<weatherAndTime> blocks; private ListAdapter adapter; // Адаптер public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Add this line in order for this fragment to handle menu events. setHasOptionsMenu(true); //Инициализируем адаптер blocks = new ArrayList<>(); // Пустой блок . } @Override public void onStart() { super.onStart(); adapter = new ListAdapter(getActivity().getApplicationContext(), blocks); // Запиливаем новый адаптер. //Вьюшка ListView listView_forecast = (ListView) getActivity().findViewById(R.id.listview_forecast); // Находим View listView_forecast.setAdapter(adapter); // Присваиваем его лист вью! //Лисенер listView_forecast.setOnItemClickListener(new AdapterView.OnItemClickListener() { // Цепляем листенер он клика че ему делать @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent showDetail = new Intent(getActivity(), DetailActivity.class). putExtra(Intent.EXTRA_TEXT, adapter.getItem(position).toString()); startActivity(showDetail); } }); } @Override public void onResume() { super.onResume(); adapter.notifyDataSetChanged(); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.forecast_fragment, menu); } @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(); if (id == R.id.action_refresh) { FetchWeatherTask weatherTask = new FetchWeatherTask(); weatherTask.execute("Omsk,RU", "json", "metric", "7"); // Запрашиваем погоду в асинхронном потоке return true; } return super.onOptionsItemSelected(item); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_main, container, false); } // Strings в AsyncTask имеется ввиду тип параметров, понятно что это массив. private class FetchWeatherTask extends AsyncTask<String, Void, ArrayList<weatherAndTime>> { // Put URL string, return list of objects private final String LOG_TAG = FetchWeatherTask.class.getSimpleName(); @Override protected ArrayList<weatherAndTime> doInBackground(String[] url_params) { if (url_params == null) { Toast.makeText(getActivity().getApplicationContext(), "Error:Параметры запроса погоды пусты", Toast.LENGTH_LONG).show(); return null; // Exit if params null } HttpURLConnection urlConnection = null; // These two need to be declared outside the try/catch BufferedReader reader = null; // so that they can be closed in the finally block. String JSON; // Will contain the raw JSON response as a string. try { // Construct the URL for the OpenWeatherMap query // Possible parameters are available at OWM's forecast API page, at // http://openweathermap.org/API#forecast // Create the request to OpenWeatherMap, and open the connection with params received. urlConnection = (HttpURLConnection) new UrlBuilder(url_params[0], url_params[1], url_params[2], Integer.parseInt(url_params[3])).getUrl().openConnection(); // Connect from builded url urlConnection.setRequestMethod("GET"); urlConnection.connect(); // Read the input stream into a String InputStream inputStream = urlConnection.getInputStream(); StringBuilder buffer = new StringBuilder(); // Был StringBuffer // Nothing to do. if (inputStream == null) return null; reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { // Since it's JSON, adding a newline isn't necessary (it won't affect parsing) // But it does make debugging a *lot* easier if you print out the completed // buffer for debugging. line += "\n"; buffer.append(line); } if (buffer.length() == 0) { // Stream was empty. No point in parsing. Toast.makeText(getActivity().getApplicationContext(), "Бля джайсон чет не пришел ХЗ", Toast.LENGTH_LONG).show(); return null; // Правоцирует IO EXCEPTION } JSON = buffer.toString(); // Получили JSON обьект парсим его JsonParser parser = new JsonParser(JSON); // Засовываем обьект в конструктор, там он сам разберется return parser.getResult(); // Возвращаем результат парсенья } catch (IOException e) { Log.e(LOG_TAG, "Error ", e); // If the code didn't successfully get the weather data, there's no point in attemping // to parse it. return null; } finally { if (urlConnection != null) { urlConnection.disconnect(); } if (reader != null) { try { reader.close(); } catch (final IOException e) { Log.e(LOG_TAG, "Error closing stream", e); } } } } @Override protected void onPostExecute(ArrayList<weatherAndTime> result) { if (result != null) { //Почему тут анчекед ассигмент и как с этим бороться blocks.clear(); //Очищает блокс blocks.addAll(result); //Обновляет blocks adapter.notifyDataSetChanged(); } } } } 

DetailActivity Code

 /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.sunshine.app; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.app.ActionBarActivity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class DetailActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* setContentView(R.layout.activity_detail); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new DetailFragment()) .commit(); } */ } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.detail, menu); 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.action_settings) { startActivity(new Intent(this, SettingsActivity.class)); return true; } return super.onOptionsItemSelected(item); } /** * A placeholder fragment containing a simple view. */ /* public static class DetailFragment extends Fragment { public DetailFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_detail, container, false); TextView DetailView = (TextView) rootView.findViewById(R.id.detailText); Intent intent = getActivity().getIntent(); if (intent != null && intent.hasExtra(Intent.EXTRA_TEXT)) DetailView.setText(intent.getStringExtra(Intent.EXTRA_TEXT)); return rootView; } }*/ } 

SettingsActivity Code

 package com.example.android.sunshine.app; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.view.KeyEvent; /** * A {@link PreferenceActivity} that presents a set of application settings. * <p> * See <a href="http://developer.android.com/design/patterns/settings.html"> * Android Design: Settings</a> for design guidelines and the <a * href="http://developer.android.com/guide/topics/ui/settings.html">Settings * API Guide</a> for more information on developing a Settings UI. */ public class SettingsActivity extends PreferenceActivity implements Preference.OnPreferenceChangeListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Add 'general' preferences, defined in the XML file // TODO: Add preferences from XML // For all preferences, attach an OnPreferenceChangeListener so the UI summary can be // updated when the preference changes. // TODO: Add preferences } /** * Attaches a listener so the summary is always updated with the preference value. * Also fires the listener once, to initialize the summary (so it shows up before the value * is changed.) */ private void bindPreferenceSummaryToValue(Preference preference) { // Set the listener to watch for value changes. preference.setOnPreferenceChangeListener(this); // Trigger the listener immediately with the preference's // current value. onPreferenceChange(preference, PreferenceManager .getDefaultSharedPreferences(preference.getContext()) .getString(preference.getKey(), "")); } @Override public boolean onPreferenceChange(Preference preference, Object value) { String stringValue = value.toString(); if (preference instanceof ListPreference) { // For list preferences, look up the correct display value in // the preference's 'entries' list (since they have separate labels/values). ListPreference listPreference = (ListPreference) preference; int prefIndex = listPreference.findIndexOfValue(stringValue); if (prefIndex >= 0) { preference.setSummary(listPreference.getEntries()[prefIndex]); } } else { // For other preferences, set the summary to the value's simple string representation. preference.setSummary(stringValue); } return true; } } 

Zakonmentirovanny pieces of code in the Detail Activity can be uncovered, it does not matter anyway does not work.

  • Show me how you shove a fragment to display in activit - Werder
  • protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); if (savedInstanceState == null) getSupportFragmentManager () .beginTransaction () .add (R.id.container, new ForecastFragment ()) .commit (); } - Julian Del Campo
  • in fact, I create a fragment in activit, in onCreate () activit, but for me it was great to find out that activit also collapses when switching to the next activit, so savedInstantState is null again, if I could create it, the fragment probably wouldn’t again, but you still need to call it somehow. - Julian Del Campo
  • Unfortunately, I still could not understand what the problem is, on another smartphone (perhaps with more memory, the activation is not destroyed). But in general, how to ensure that the activity is not destroyed? - Julian Del Campo

1 answer 1

Each time, calling new ForecastFragment() , you create a new instance of the fragment that is inside itself and jerks onCreate. Therefore, I advise you to add a fragment tag as the third parameter to the add method, and before re-committing to check if there is already such a fragment in the getSupportFragmentManager().findFragmentByTag(fragmentTag); this is done by the getSupportFragmentManager().findFragmentByTag(fragmentTag); method), and if there is, replace it instead of new ForecastFragment()

A good example on the topic is painted here.

Update

 if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction().add(R.id.container, new ForecastFragment(), "TAG").commit(); } else { ForecastFragment fragment = (ForecastFragment) getSupportFragmentManager().findFragmentByTag("TAG"); getSupportFragmentManager().beginTransaction().add(R.id.container, fragment, "TAG").commit(); } 
  • But it can be an approximate working piece of code, I'm with fragments on you. - Julian Del Campo
  • java.lang.IllegalStateException: Fragment already added. - Julian Del Campo
  • when returning from any other activites, to the mine activations. - Julian Del Campo
  • The last line in your code causes an error ... - Julian Del Campo
  • Do this - if according to the tag the manager could find a fragment, then you have several options: 1) instead of add, call replace, that is, replace the previous fragment with the same one. 2) do not call the add method at all, then the same fragment is displayed that is already stored in the manager - Werder