Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
KorPaEv
53 / 29 / 3
Регистрация: 08.07.2011
Сообщений: 185
#1

Сохранение данные при переходе на другой активити - Android

25.11.2015, 08:39. Просмотров 446. Ответов 9
Метки нет (Все метки)

Доброго времени суток, уважаемые!
Вопрос заезжан и много инфы в инете, но прочитав и попробовав наткнулся на пару стен, соответственно полез на форум, может быть вы меня ткнете в мои ошибки!
Итак - имеем 2 активити и общее меню, при клике в меню для перехода на новую активити срабатывает метод создания активити - код приведу ниже, соответственно на новой ативити есть пункт меню для перехода на 1ю активити - там так же вызывается метод создания новой активити.
Теперь моя проблема и код.

1я активити содержит меню, метод сохранения данных и тд.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package com.example.SmartHome;
 
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
 
public class MainActivity extends Activity {
 
    EditText ePhone;
    SharedPreferences mSharedPref;
    CheckBox chbOne, chbTwo, chbThree, chbFour;
 
    private final String PHONEPERF = "Saved phone number";
    private String KEY_CHB_RELAY_ONE = "false";
    private String KEY_CHB_RELAY_TWO = "false";
    private final  String KEY_CHB_RELAY_THREE = "false";
    private final  String KEY_CHB_RELAY_FOUR = "false";
 
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        FindViews(); //Нахожу View
        LoadPerf(); //Загружаю сохраненный номер из настроек приложения
        onLoadInstanceState(savedInstanceState); //Загружаю сохраненные данные при переходе обратно
       }
 
    protected void FindViews()
    {
        ePhone = (EditText) findViewById(R.id.ePhoneNum);
        chbOne = (CheckBox) findViewById(R.id.chbRelayOne);
        chbTwo = (CheckBox) findViewById(R.id.chbRelayTwo);
        chbThree = (CheckBox) findViewById(R.id.chbRelayThree);
        chbFour = (CheckBox) findViewById(R.id.chbRelayFour);
    }
 
    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState)
    {
        if (chbOne.isChecked())
            savedInstanceState.putString(KEY_CHB_RELAY_ONE, "true");
        else savedInstanceState.putString(KEY_CHB_RELAY_ONE, "false");
 
        if (chbTwo.isChecked())
            savedInstanceState.putString(KEY_CHB_RELAY_TWO, "true");
        else savedInstanceState.putString(KEY_CHB_RELAY_TWO, "false");
 
        if (chbThree.isChecked())
            savedInstanceState.putString(KEY_CHB_RELAY_THREE, "true");
        else savedInstanceState.putString(KEY_CHB_RELAY_THREE, "false");
 
        if (chbFour.isChecked())
            savedInstanceState.putString(KEY_CHB_RELAY_FOUR, "true");
        else savedInstanceState.putString(KEY_CHB_RELAY_FOUR, "false");
 
        super.onSaveInstanceState(savedInstanceState);
    }
 
 
   // @Override
    protected void onLoadInstanceState(Bundle savedInstanceState)
    {
        if (savedInstanceState != null)
        {
            if (savedInstanceState.getString(KEY_CHB_RELAY_ONE) == "true")
                chbOne.setChecked(true);
            else chbOne.setChecked(false);
 
            if (savedInstanceState.getString(KEY_CHB_RELAY_TWO) == "true")
                chbTwo.setChecked(true);
            else chbTwo.setChecked(false);
 
            if (savedInstanceState.getString(KEY_CHB_RELAY_THREE) == "true")
                chbThree.setChecked(true);
            else chbThree.setChecked(false);
 
            if (savedInstanceState.getString(KEY_CHB_RELAY_FOUR) == "true")
                chbFour.setChecked(true);
            else chbFour.setChecked(false);
        }
    }
 
    //создаем меню
    @Override
    public boolean onCreateOptionsMenu(Menu currMenu) {
        super.onCreateOptionsMenu(currMenu);
 
        //заполняем меню
        getMenuInflater().inflate(R.menu.menu_main, currMenu);
        if (currMenu != null)
            currMenu.findItem(R.id.main_inf).setVisible(false);
        return true;
    }
 
    //событие на выбранный пункт меню
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // получаем все пункты меню
        //пункт item определен в menu_main
        int itemId = item.getItemId();
        Intent intent;
 
        // ищем наш пункт меню
        switch (itemId) {
            case R.id.about:
                intent = new Intent(MainActivity.this, AboutActivity.class);
                startActivity(intent);
                return true;
            case R.id.conf:
                intent = new Intent(MainActivity.this, SettingsActivity.class);
                startActivity(intent);
                return true;
            case R.id.names:
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
 
    public void ButtonClick(View view)
    {
        String strPhone = "";
        if (ePhone.getText().length() != 0)
            strPhone = ePhone.getText().toString();
        switch(view.getId())
        {
            case  R.id.bUpd:
            {
                break;
            }
            case  R.id.ibSavePerf:
            {
                SavePerf(view, strPhone);
                break;
            }
        }
    }
 
    //Обрабатываем нажатие кнопки "Сохранить":
    public void SavePerf(View view, String str) {
 
        //Создаем экземпляр для хранения данных SharedPreferences, выставляем доступ MODE_PRIVATE:
        mSharedPref = getPreferences(MODE_PRIVATE);
 
        //Создаем объект Editor для создания пар имя-значение:
        SharedPreferences.Editor mEditor = mSharedPref.edit();
 
        //Сохраняем введенные символы в поля ввода, задавая имена USERNAME,
        //PASSWORD и соответствующие им значения, получаемые из полей ввода:
        mEditor.putString(PHONEPERF, str);
 
        //Совершаем сохранение того, что мы тут наворотили:
        mEditor.commit();
 
        //Показываем Toast сообщение о том, что дело сделано:
        Toast.makeText(this, "Номер сохранен!", Toast.LENGTH_SHORT).show();
    }
 
    //Загрузить сохраненный номер из настроек приложения
    public void LoadPerf() {
 
        //Используем созданный файл данных SharedPreferences:
        mSharedPref = getPreferences(MODE_PRIVATE);
 
        //Создаем строковый объект, берем значение из сохраненных данных:
        String savedNumb = mSharedPref.getString(PHONEPERF, "");
        if (savedNumb == "")
        {
            ePhone.setText("");
            ePhone.setHint("Введите номер");
        }
 
        //Присваиваем вытащенные значения полям ввода:
        ePhone.setText(savedNumb);
 
        //Показываем Toast сообщение о том, что дело сделано:
        Toast.makeText(this, "Данные загружены", Toast.LENGTH_SHORT).show();
    }
}
Возникло 2 проблемы - в отладчике когда я жму на кнопку перехода на 2 экран у меня осуществляется переход сюда

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState)
    {
        if (chbOne.isChecked())
            savedInstanceState.putString("KEY_CHB_RELAY_ONE", "true");
        else savedInstanceState.putString("KEY_CHB_RELAY_ONE", "false");
 
        if (chbTwo.isChecked())
            savedInstanceState.putString(KEY_CHB_RELAY_TWO, "true");
        else savedInstanceState.putString(KEY_CHB_RELAY_TWO, "false");
 
        if (chbThree.isChecked())
            savedInstanceState.putString(KEY_CHB_RELAY_THREE, "true");
        else savedInstanceState.putString(KEY_CHB_RELAY_THREE, "false");
 
        if (chbFour.isChecked())
            savedInstanceState.putString(KEY_CHB_RELAY_FOUR, "true");
        else savedInstanceState.putString(KEY_CHB_RELAY_FOUR, "false");
 
        super.onSaveInstanceState(savedInstanceState);
    }
соответственно у меня выбран чекбокс 1, но при том, что он выбран не отрабатывает

Java
1
savedInstanceState.putString("KEY_CHB_RELAY_ONE", "true");
не пойму почему, но отладчик показывает KEY_CHB_RELAY_ONE = "false" переменная не переписывается
Это первое
Далее если же я меняю эту строку на

Java
1
savedInstanceState.putString("aaa", "true");
то в "aaa" записывается true и условие якобы отрабатывает
Дальше я перескакиваю на вторую активити, где так же есть меню с пунктом для первого активити и обработкой нажатий на пункты меню

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.example.SmartHome;
 
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
 
public class AboutActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about);
    }
 
    //создаем меню
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        super.onCreateOptionsMenu(menu);
        //заполняем меню
        getMenuInflater().inflate(R.menu.menu_main, menu);
        if (menu != null)
            menu.findItem(R.id.about).setVisible(false);
        return true;
    }
 
    //событие на выбранный пункт меню
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        // получаем все пункты меню
        //пункт item определен в menu_main
        int itemId = item.getItemId();
        Intent intent;
 
        // ищем наш пункт меню
        switch (itemId)
        {
            case R.id.conf:
                intent = new Intent(AboutActivity.this, SettingsActivity.class);
                startActivity(intent);
                return true;
            case R.id.names:
 
                return true;
            case R.id.main_inf:
                intent = new Intent(AboutActivity.this, MainActivity.class);
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}
Соответственно когда я тыкаю для возврата на первую активити у меня происходит его пересоздание - поле текстовое заполняется из настроек все норм, отладчик дальше идет в загрузку

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   // @Override
    protected void onLoadInstanceState(Bundle savedInstanceState)
    {
        if (savedInstanceState != null)
        {
            if (savedInstanceState.getString(KEY_CHB_RELAY_ONE) == "true")
                chbOne.setChecked(true);
            else chbOne.setChecked(false);
 
            if (savedInstanceState.getString(KEY_CHB_RELAY_TWO) == "true")
                chbTwo.setChecked(true);
            else chbTwo.setChecked(false);
 
            if (savedInstanceState.getString(KEY_CHB_RELAY_THREE) == "true")
                chbThree.setChecked(true);
            else chbThree.setChecked(false);
 
            if (savedInstanceState.getString(KEY_CHB_RELAY_FOUR) == "true")
                chbFour.setChecked(true);
            else chbFour.setChecked(false);
        }
    }
и тут я вижу что savedInstanceState = null
Либо при создании из второй активити оно обнуляется, но должно же сохраняться судя по урокам у всех все работает, например отсюда
http://pr0andr0id.blogspot.ru/2014/04/3.html
там так же создается активити новое но при возврате savedInstanceState != null
Соответственно мой выбранный чекбокс не восстанавливается

Какие есть предположения куда копать что не правильно?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.11.2015, 08:39     Сохранение данные при переходе на другой активити
Посмотрите здесь:

Android Ошибка при переходе на другой экран (Eclipse)
Android Закрытие одной активити из другой
Обращение к элементам другой Активити Android
Переход на другой активити (список) Android
Android Как отобразить ViewPager внутри другой активити
Android Сохранение введенных данных при переходе на другой activity
Вылет при переходе на второй активити Android
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Паблито
2011 / 1753 / 545
Регистрация: 12.05.2014
Сообщений: 6,207
Завершенные тесты: 1
25.11.2015, 13:05     Сохранение данные при переходе на другой активити #2
многовато кода и текста, для начала предлагаю исправить бред типа
bundle.putString ("","true");
на
bundle.putBoolean("", true);
KorPaEv
53 / 29 / 3
Регистрация: 08.07.2011
Сообщений: 185
25.11.2015, 13:25  [ТС]     Сохранение данные при переходе на другой активити #3
Паблито, Это я уже исправил все...нашел где ошибки, у меня открытым остался вопрос, почему при смене активити именно через меню, при его создании у меня обнуляется сохраненный savedInstanceState

Добавлено через 6 минут
Паблито, упростим
Активити 1
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class MainActivity extends Activity {
 
     ToggleButton tgbOne;
    private final String TGBRELAYONE = "Relay one state";
 
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        FindViews();
        onLoadInstanceState(savedInstanceState);
    }
 
    protected void FindViews()
    {
        tgbOne = (ToggleButton) findViewById(R.id.tgbRelayOne);
    }
 
    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState)
    {
        String tgb1;
        tgb1 = String.valueOf(tgbOne.isChecked());
        savedInstanceState.putString(TGBRELAYONE, tgb1);
        super.onSaveInstanceState(savedInstanceState);
    }
 
 
   // @Override
    protected void onLoadInstanceState(Bundle savedInstanceState)
    {
        if (savedInstanceState != null)
        {
            Boolean tgb1;
            tgb1 = Boolean.parseBoolean(mSharedPref.getString(TGBRELAYONE, ""));
             tgbOne.setChecked(tgb1);
        }
    }
 
    //создаем меню
    @Override
    public boolean onCreateOptionsMenu(Menu currMenu) {
        super.onCreateOptionsMenu(currMenu);
 
        //заполняем меню
        getMenuInflater().inflate(R.menu.menu_main, currMenu);
        if (currMenu != null)
            currMenu.findItem(R.id.main_inf).setVisible(false);
        return true;
    }
 
    //событие на выбранный пункт меню
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
 
        int itemId = item.getItemId();
        Intent intent;
 
        switch (itemId) {
            case R.id.about:
                intent = new Intent(MainActivity.this, AboutActivity.class);
                startActivity(intent);
                return true;
             default:
                return super.onOptionsItemSelected(item);
        }
    }
}
И 2 активити
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class AboutActivity extends Activity {
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about);
    }
 
    //создаем меню
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        super.onCreateOptionsMenu(menu);
        //заполняем меню
        getMenuInflater().inflate(R.menu.menu_main, menu);
        if (menu != null)
            menu.findItem(R.id.about).setVisible(false);
        return true;
    }
 
    //событие на выбранный пункт меню
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        int itemId = item.getItemId();
        Intent intent;
 
        // ищем наш пункт меню
        switch (itemId)
        {
            case R.id.main_inf:
                intent = new Intent(AboutActivity.this, MainActivity.class);
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}
Соответственно при смене состояния кнопки на 1 активити, далее при переходе на второй и возврате по меню обратно у меня состояние кнопки не сохраняется
Паблито
2011 / 1753 / 545
Регистрация: 12.05.2014
Сообщений: 6,207
Завершенные тесты: 1
25.11.2015, 13:30     Сохранение данные при переходе на другой активити #4
мне лениво писать очевидные вещи, проще дать ссылку на "как правильно"
http://stackoverflow.com/questions/1...ate-on-android

в коде выше все еще ложатся стринги, вместо boolean и зачем-то вызывается onLoadInstanceState из onCreate
KorPaEv
53 / 29 / 3
Регистрация: 08.07.2011
Сообщений: 185
25.11.2015, 13:46  [ТС]     Сохранение данные при переходе на другой активити #5
Паблито, на самом деле разницы особо нет написать так
Java
1
2
3
4
5
6
7
8
@Override
    protected void onSaveInstanceState(Bundle savedInstanceState)
    {
        String tgb1;
        tgb1 = String.valueOf(tgbOne.isChecked());
        savedInstanceState.putString(TGBRELAYONE, tgb1);
        super.onSaveInstanceState(savedInstanceState);
    }
или так

Java
1
2
3
4
5
6
7
8
    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState)
    {
        Boolean tgb1;
        tgb1 = tgbOne.isChecked();
        savedInstanceState.putBoolean(TGBRELAYONE, tgb1);
        super.onSaveInstanceState(savedInstanceState);
    }
а по поводу зачем я вызываю onLoadInstanceState из onCreate аналогично - разницы нет - вызвать его явно ручками, обозвав по своиму из onCreate и передать в него savedInstanceState или переопределить вот так

Java
1
2
@Override
public void onRestoreInstanceState(Bundle savedInstanceState)
Добавлено через 58 секунд
Паблито, только это не решает проблему с созданием 1го активити из 2го и обнулением того самого savedInstanceState
Паблито
2011 / 1753 / 545
Регистрация: 12.05.2014
Сообщений: 6,207
Завершенные тесты: 1
25.11.2015, 14:05     Сохранение данные при переходе на другой активити #6
у меня к сожалению нет на чем проверить, но я уверен что методы onRestoreInstanceState и onSaveInstanceState
вызываются далеко не каждый раз и не факт что они вызовутся когда из одной активити стартует другая

вывод в лог если туда запихнуть что бы проверить, заходит ли туда вообще?
KorPaEv
53 / 29 / 3
Регистрация: 08.07.2011
Сообщений: 185
25.11.2015, 14:17  [ТС]     Сохранение данные при переходе на другой активити #7
Паблито, уже проверил, как раз при переходе из 2го активити на первый именно когда срабатывает на 2м активити вот эта штука

Java
1
2
intent = new Intent(AboutActivity.this, MainActivity.class);
                startActivity(intent);
если переопределить метод в первом активити

Java
1
2
3
4
5
6
7
8
 @Override
    protected void onSaveInstanceState(Bundle savedInstanceState)
    {
        Boolean tgb1;
        tgb1 = tgbOne.isChecked();
        savedInstanceState.putBoolean(TGBRELAYONE, tgb1);
        super.onSaveInstanceState(savedInstanceState);
    }
в него я не попадаю, если же как написал выше ручками вызвать из onCreate то в него я попадаю но там уже saveInstance = null
Выходит что при создании нового активити saveInstance все же обнуляется и тогда вопрос - каким образом сохраненный в 1м активити saveInstance можно передать на 2ой и потом соответственно обратно?
Паблито
2011 / 1753 / 545
Регистрация: 12.05.2014
Сообщений: 6,207
Завершенные тесты: 1
25.11.2015, 14:22     Сохранение данные при переходе на другой активити #8
а почему не использовать SharedPreferences ?
там вообще пара строк - в onPause все сохраняем, а в onResume - все вычитываем и прописываем на кнопки и все такое
KorPaEv
53 / 29 / 3
Регистрация: 08.07.2011
Сообщений: 185
25.11.2015, 14:28  [ТС]     Сохранение данные при переходе на другой активити #9
Паблито, неверно написал...если переопределить вот так
Java
1
2
@Override
public void onRestoreInstanceState(Bundle savedInstanceState)
то отладчик туда не заходит, если же ручками вызываю в onCreate то заходит туда но там пусто..ну и тд

Добавлено через 3 минуты
Паблито, на самом деле я его уже использую (SharedPreferences) но только для сохранения настроек тех, которые мне надо восстанавливать при каждом новом запуске приложения...
видимо придется и им разруливать эту ситуацию...
ТОгда сразу еще вопрос возник по SharedPreferences - при выходе из приложения каким образом его вызывать
Саму функцию я подготовил сохранения и чтения
как повешать функцию на событие закрытия приложения?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.11.2015, 15:28     Сохранение данные при переходе на другой активити
Еще ссылки по теме:

При переходе между активити возникает ошибка Android
Сохранение данных при пересоздании активити Android
Android Изменить элемент одной активити из другой
Передать данные в активити Android
Android Сохранение набранного в EditText текста при смене активити

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Паблито
2011 / 1753 / 545
Регистрация: 12.05.2014
Сообщений: 6,207
Завершенные тесты: 1
25.11.2015, 15:28     Сохранение данные при переходе на другой активити #10
Цитата Сообщение от KorPaEv Посмотреть сообщение
как повешать функцию на событие закрытия приложения?
я ж говорю - в onPause() можно все сохранять
Yandex
Объявления
25.11.2015, 15:28     Сохранение данные при переходе на другой активити
Ответ Создать тему
Опции темы

Текущее время: 18:54. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru