Для чего используется RESULT_OK и getBooleanExtra?
Есть код дочерней активности, которая получает информацию от главной, затем возвращает в главную активность информацию о том, нажимал ли пользователь кнопку для получения этой информации:
public class CheatActivity extends AppCompatActivity {
private static final String EXTRA_ANSWER_IS_TRUE =
"com.bignerdranch.android.geoquiz.answer_is_true"; // ключ для получения дополнения с правильным ответом
private static final String EXTRA_ANSWER_SHOWN =
"com.bignerdranch.android.geoquiz.answer_shown"; // ключь для передачи данных о том, видел ли пользовательно ответ
private boolean mAnswerIsTrue; // правильный ответ
private TextView mAnswerTextView;
private Button mShowAnswerButton;
public static Intent newIntent(Context packageContext, boolean answerIsTrue) { // с помощью этого метода главная активность передаёт данные в дочернию
Intent intent = new Intent(packageContext, CheatActivity.class);
intent.putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue);
return intent;
}
public static boolean wasAnswerShown(Intent result) { // упрощае декодирование данных к виду, который может использовать QuizActivity (с 129)
return result.getBooleanExtra(EXTRA_ANSWER_SHOWN, false); // getBooleanExtra - метод для чтения значения из дополнения
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat);
mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false); // получение данных из intent
mAnswerTextView = (TextView) findViewById(R.id.answer_text_view);
mShowAnswerButton = (Button) findViewById(R.id.show_answer_button);
mShowAnswerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mAnswerIsTrue) {
mAnswerTextView.setText(R.string.true_button);
} else {
mAnswerTextView.setText(R.string.false_button);
}
setAnswerShownResult(true);
}
});
}
private void setAnswerShownResult(boolean isAnswerShown) { // возвращает в главную активность информацию о том, подсматривал ли пользователь ответ
Intent data = new Intent();
data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown); // передайт true, если пользовательно подсматривал ответ (вторая переменная)
setResult(RESULT_OK, data); // возвращает данные в главную активность
}
}
Меня интересуют 2 метода:
Метод:
public static boolean wasAnswerShown(Intent result) { // упрощае декодирование данных к виду, который может использовать QuizActivity (с 129)
return result.getBooleanExtra(EXTRA_ANSWER_SHOWN, false); // getBooleanExtra - метод для чтения значения из дополнения
}
И метод:
private void setAnswerShownResult(boolean isAnswerShown) { // возвращает в главную активность информацию о том, подсматривал ли пользователь ответ
Intent data = new Intent();
data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown); // передайт true, если пользовательно подсматривал ответ (вторая переменная)
setResult(RESULT_OK, data); // возвращает данные в главную активность
}
}
При удалении любого из этих методов, при возвращении на главную активность перестаёт выводится сообщение о том, что пользователь нажал на кнопку с правильным ответом. Однако я не понимаю в чём заключается взаимодополняющая роль эти методов, мне кажется, что они делают примерно одно и то же. Подскажите, пожалуйста, что делают эти методы (так как я видимо ошибаюсь в этом) и как они между собой связаны
Код главной активности:
public class QuizActivity extends AppCompatActivity {
private static final String TAG = "QuizActivity";
private static final String KEY_INDEX = "index"; // ключ, нужный для сохранения значения индекса мнежду поворотами сматрфона
private static final int REQUEST_CODE_CHEAT = 0;
private Button mTrueButton;
private Button mFalseButton;
private Button mNextButton;
private Button mCheatButton;
private TextView mQuestionTextView;
private Question[] mQuestionBank = new Question[] { // так как этот массив ссылвется на объект класса Question,
//я могу вызывать из него методы класса Question
new Question(R.string.question_australia, true),
new Question(R.string.question_oceans, true),
new Question(R.string.question_mideast, false),
new Question(R.string.question_africa, false),
new Question(R.string.question_americas, true),
new Question(R.string.question_asia, true),
};
private int mCurrentIndex = 0;
private boolean mIsCheater;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
Log.d(TAG, "onCreate(Bundle) called");
if (savedInstanceState != null) {
mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0); // извлечение сохранённого индекса из Bundle,
// если он существует (не равен null)
}
mQuestionTextView = (TextView) findViewById(R.id.question_text_view);
mTrueButton = (Button) findViewById(R.id.true_button);
mTrueButton.setOnClickListener(new View.OnClickListener() { // Изучить тему анонимных классов и слушателей
@Override
public void onClick(View v) {
checkAnswer(true);
}
});
mFalseButton = (Button) findViewById(R.id.false_button);
mFalseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkAnswer(false);
}
});
mNextButton = (Button) findViewById(R.id.next_button);
mNextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCurrentIndex = (mCurrentIndex + 1) % mQuestionBank.length;
mIsCheater = false;
updateQuestion();
}
});
mCheatButton = (Button)findViewById(R.id.cheat_button);
mCheatButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Start CheatActivity
boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();
Intent intent = CheatActivity.newIntent(QuizActivity.this, answerIsTrue);
startActivityForResult(intent, REQUEST_CODE_CHEAT); // не только отправляет информацию, но и получает обратную связь
}
});
updateQuestion();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { // метод, с помощью которого активность узнаёт, жёльничал ли пользователь
//для того, чтобы, если он жульничал, поменять значение во всплывающем окне
// на "Cheating is wrong.", это происходит в методе checkAnswer
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE_CHEAT) {
if (data == null) {
return;
}
mIsCheater = CheatActivity.wasAnswerShown(data); // если пользователь жульничал, переменной mIsCheater присваивается значение true
}
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart() called");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume() called");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause() called");
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.i(TAG, "onSaveInstanceState");
savedInstanceState.putInt(KEY_INDEX, mCurrentIndex); // сохранение индекса в Bundle
}
@Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop() called");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy() called");
}
private void updateQuestion() { // вставляет в TextView вопрос в соответствии с его индексом
int question = mQuestionBank[mCurrentIndex].getTextResId();
mQuestionTextView.setText(question);
}
private void checkAnswer(boolean userPressedTrue) {
boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();
int messageResId = 0;
if (mIsCheater) {
messageResId = R.string.judgment_toast;
} else {
if (userPressedTrue == answerIsTrue) {
messageResId = R.string.correct_toast;
} else {
messageResId = R.string.incorrect_toast;
}
}
Toast.makeText(this, messageResId, Toast.LENGTH_SHORT)
.show();
}
}
Класс Question:
public class Question {
private int mTextResId;
private boolean mAnswerTrue;
public Question(int textResId, boolean answerTrue) {
mTextResId = textResId;
mAnswerTrue = answerTrue;
}
public int getTextResId() {
return mTextResId;
}
public void setTextResId(int textResId) {
mTextResId = textResId;
}
public boolean isAnswerTrue() {
return mAnswerTrue;
}
public void setAnswerTrue(boolean answerTrue) {
mAnswerTrue = answerTrue;
}
}
P.S. в комментариях я попытался указать своё понимание того, что происходит в коде
Ответы (1 шт):
С добавлением кода главной активности все, вроде бы, стало понятно.
Если в двух словах, то методы wasAnswerShown и setAnswerShownResult являются getter'ом и setter'ом соответственно. То есть setAnswerShownResult позволяет сохранить значение (пока будем считать, что просто где-то сохранить), а метод wasAnswerShown - получить значение, которое сохранил setAnswerShownResult.
Теперь о том, как именно это происходит у Вас.
Сначала главная активность запускает CheatActivity:
startActivityForResult(intent, REQUEST_CODE_CHEAT);
Если в CheatActivity пользователь нажимает на кнопку, то вызывается метод setAnswerShownResult:
private void setAnswerShownResult(boolean isAnswerShown) {
Intent data = new Intent();
data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown);
setResult(RESULT_OK, data);
}
Строка Intent data = new Intent(); - создаем Intent, думаю тут вопросов нет.
Строка data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown); - добавляем в созданный выше Intent информацию. Храним информацию по ключу EXTRA_ANSWER_SHOWN (это как номер ячейки в банке, без него не найдем то, что сохранили).
Строка setResult(RESULT_OK, data); завершить активность с результатом RESULT_OK (то есть сигнализируем, что ошибок нет) и вернуть в MainActivity data (наш Intent с данными).
После вызова setResult CheatActivity уничтожается. Запускается MainActivity, система вызывает метод onActivityResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE_CHEAT) {
if (data == null) {
return;
}
mIsCheater = CheatActivity.wasAnswerShown(data);
}
}
Теперь снова разбор по строкам:
if (resultCode != Activity.RESULT_OK) {
return;
}
resultCode будет равен RESULT_OK только если мы вызвали setAnswerShownResult. Соответственно, если не равен - то делать ничего не надо.
if (requestCode == REQUEST_CODE_CHEAT) - проверяем, что произошел возврат именно из CheatActivity.
Этот же ключик REQUEST_CODE_CHEAT мы использовали при запуске startActivityForResult(intent, REQUEST_CODE_CHEAT);
В реальных приложениях можно встретить ситуацию, когда возврат возможен с доброго десятка активностей, так что за кодом REQUEST_CODE_CHEAT надо привыкать следить. Для каждой активности код, конечно, должен быть уникален.
if (data == null) {
return;
}
Тут, вроде, все понятно. Если данных нет, то и делать ничего не надо.
mIsCheater = CheatActivity.wasAnswerShown(data);
Мы пришли к вызову wasAnswerShown. По сути, метод просто достает данные из data.
Рассмотрим его код:
public static boolean wasAnswerShown(Intent result) {
return result.getBooleanExtra(EXTRA_ANSWER_SHOWN, false);
}
result - это то, что раньше называлось data.
result.getBooleanExtra(EXTRA_ANSWER_SHOWN, false); - Пытаемся найти значение типа bool по ключу EXTRA_ANSWER_SHOWN.
Подытожу:
Activity.RESULT_OKпозволяет указать, что активность завершилась нормально, без ошибок.getBooleanExtra- позволяет получить изIntentранее сохраненное значение типаboolпо ключу