Хранение и восстановление состояний активности
Могу ли я быть уверен, что при вызове другого действия переменная, сохраненная в текущем действии, будет присутствовать при ее возврате?
new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter, View item, int pos, long id) {
Intent i = new Intent(Activity1.this, Activity2.class);
i.putExtra("position", pos); // 1
position = pos; // 2
startActivityForResult(i, REQUEST_CODE); // brings up the edit item activity
}
});
Для приведенного выше кода могу ли я использовать (2), сохраняя в текущем поле экземпляра активности, или я должен передать значение с помощью (1), а затем использовать getIntExtra()
в onActivityResult()
восстановить это значение?
4 ответа
В идеале вы бы просто сохранить состояние в Activity1
, Таким образом, вам не придется передавать переменную через Activity2
а затем передать результат (который не совсем результат чего-либо сделанного в Activity2
) вернуться к Activity1
, Чтобы сохранить значение position
в Activity1
Вы должны сделать следующее внутри вашего Activity
:
private static final String KEY_ARG_POSITION = "KEY_ARG_POSITION";
private int position;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Do whatever you are doing in onCreate already...
if (savedInstanceState != null) {
position = savedInstanceState.getInt(KEY_ARG_POSITION);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(KEY_ARG_POSITION, position);
}
Это также актуально, если вы не хотите терять это значение при изменении ориентации экрана или когда ОС убивает и перезапускает вашу активность.
Наконец, просто для того, чтобы сохранить ваш код организованным, если вам не нужно использовать значение position
в Activity2
Я бы порекомендовал не выставлять Activity2
к любым данным, которыми он не должен управлять. Если вы работаете с большим приложением, такие вещи могут сложиться и быстро запутаться.
Да, он появится, когда вы вернетесь к Activity1, поэтому нет необходимости использовать getIntExtra
, Просто сохраните вашу позицию в глобальной переменной Activity1.
При использовании startActivityForResult... вы предоставляете код запроса, который будет возвращен в вашем методе onActivityResult. Там вы получите код запроса, а также код результата (Успех, сбой и т. Д.), А также данные о намерениях, которые вы можете установить из начального действия.
Так что вы можете сделать:
Intent i = new Intent(Activity1.this, Activity2.class);
i.putExtra("position", pos);
startActivityForResult(i, REQUEST_CODE);
а затем в вашем классе Activity2
Intent intent = new Intent();
intent.putExtras(getIntent().getExtra("position"));
setResult(RESULT_OK, intent);
finish();
который в вашей первой деятельности будет называть:
onActivityResult(int requestCode, int resultCode, Intent data) {
//Check it's your requestCode,
//Check resultCode == RESULT_OK or whatever you need
//Grab your position from the data intent
}
См. https://developer.android.com/training/basics/intents/result.html для получения дополнительной информации.
Мой совет: передайте достаточно информации в Intent
уникально идентифицировать интересующий элемент данных. Не просто проходите позицию, потому что позиции могут измениться, если порядок элементов изменяется или другие элементы добавляются / удаляются из списка. Представьте себе сценарий, в котором вы проходите позицию 2 для Activity2
, но пока Activity2
вверх, Activity1
перезагружает свои данные и позиция 2 теперь является другим элементом.
Кроме того, я бы не стал полагаться на экземпляр члена вызывающей операции (т.е. position = pos
в вашем коде). Это возможно для вашего Activity1
быть убитым, в то время как другая деятельность является непосредственной приоритетной деятельностью. В этом случае он будет воссоздан, когда результат будет возвращен Activity1
, но это будет новый экземпляр Activity1, так что ваш экземпляр члена position
не будет данных, которые вы установили ранее.