У меня есть два вида деятельности:
Задание №1: SetListMasterViewActivity
Задание №2: SetListOpenViewActivity
Действие №1 изначально вызывает Действие №2 с переменными Intent
, и это работает нормально. Задание №1 содержит List
песен. Когда пользователь нажимает на любую песню в списке, песня открывается со всеми текстами песен из задания №2. Нажимая кнопку «Назад» в Действии № 2, пользователь снова возвращается к списку в Действии № 1, но на этот раз песня, ранее просматривавшаяся в Действии № 2, теперь выделяется (в списке в Действии № 1).
Когда пользователь нажимает "Back"
из действия № 2 (отправка обработки обратно в действие № 1), у меня возникает проблема. Логика заключается в том, что в Упражнении №2 пользователь просматривает текст песни (текст песни). Когда пользователь нажимает кнопку "Back"
, обработка возвращается к действию № 1, и песня, которую пользователь просматривал в действии № 2, теперь выделена в списке.
В действии №2 внутри onCreate()
приведен код "Back"
, где я установил намерение:
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int currentPosition = getCurrentPosition(songName, songsList);
String currentSongName = songsList.get(currentPosition);
int currentSongId = getSongIdByName(currentSongName);
Intent resultIntent = new Intent();
resultIntent.putExtra("lastViewedSongId", currentSongId);
resultIntent.putExtra("lastViewedSongName", currentSongName);
setResult(RESULT_OK, resultIntent);
finish();
startSetListMasterViewActivity();
}
});
После запуска Intent
обработка продолжается следующим методом:
private void startSetListMasterViewActivity() {
Intent intent = new Intent(SetListOpenViewActivity.this, SetListMasterViewActivity.class);
Log.d("SttList", "(SetListOpenViewActivity) line #194 - Launching SetListMasterViewActivity");
setListMasterViewLauncher.launch(intent);
}
Что вызывает этот метод:
private final ActivityResultLauncher<Intent> setListMasterViewLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
Log.d("SttList", "(SetListOpenViewActivity) line #208 - ActivityResultLauncher");
if (result.getResultCode() == Activity.RESULT_OK) {
// ...
}
}
);
В рамках действия № 1 здесь получен Intent
:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("SttList", "(SetListMasterViewActivity) line #191 - onActivityResult called");
Log.d("SttList", "(SetListMasterViewActivity) line #192 - requestCode: " + requestCode + ", resultCode: " + resultCode);
if (requestCode == REQUEST_CODE_SET_LIST_MASTER && resultCode == RESULT_OK && data != null) {
// Retrieve the last viewed song information from the Intent
int lastViewedSongId = data.getIntExtra("lastViewedSongId", -1);
String lastViewedSongName = data.getStringExtra("lastViewedSongName");
// Find the position of the last viewed song in list of song names
int position = songNames.indexOf(lastViewedSongName);
// Log the received data
Log.d("SttList", "(SetListMasterViewActivity) line #201 - Received lastViewedSongId: " + lastViewedSongId);
Log.d("SttList", "(SetListMasterViewActivity) line #202 - Received lastViewedSongName: " + lastViewedSongName);
// Highlight the song
if (position != -1) {
// Highlight the song at the found position
TextView songTextView = (TextView) songsListView.getChildAt(position);
songTextView.setBackgroundColor(Color.YELLOW);
}
}
}
Что происходит, так это то, что действие № 1 открывается, но ни одно из намерений из действия № 2 не получено. Все операторы Log.d в onActivityResult
не выполняются, поэтому кажется, что onActivityResult
пропускается целиком.
Я попытался переместить весь код из onActivityResult
в onResume
- в Упражнении № 1 - но обнаружил, что Intent
не получен в onResume
. Я просмотрел другие опубликованные проблемы, но не могу найти проблему, с которой столкнулся.
Что еще я пробовал:
setResult()
- это то, что вам нужно, чтобы он позвонил onActivityResult()
-
да, я использую setResult()
setResult
я использую setResult(RESULT_OK, resultIntent);
startActivityForResult
, который используется во многих старых ответах, однако это обесценивается, поскольку AS заявляет: 'startActivityForResult(android.content.Intent, int)' is deprecated
Спасибо за ваше наблюдение @ianhanniballake — родительское действие (действие № 1) передает данные дочернему действию (действие № 2), а затем дочернее действие передает данные обратно родительскому действию. Я не начинаю новую деятельность – нет необходимости начинать новую деятельность; вместо этого я просто возвращаю данные родительскому действию.
Я возвращаюсь к родителю и не начинаю новую деятельность – это было залогом движения вперед. Я считаю, что проблема была решена путем изменения способа реализации дочерней активности и использования ActivityResultLauncher
. После кодирования все работает! @ianhanniballake, твой комментарий помог мне пойти по абсолютно правильному пути. Если вы отправите свой комментарий в качестве ответа, я отдам вам должное и закрою это дело. Большое спасибо за помощь!
родительское действие (действие № 1) передает данные дочернему действию (действие № 2), а затем дочернее действие передает данные обратно родительскому действию.
Важная часть заключается в том, что API результатов активности предназначен только для возврата результата — передачи результата из вашей дочерней активности обратно в родительскую активность.
Это означает, что родительская активность отвечает за вызов registerForActivityResult
с соответствующим контрактом. Он будет включать информацию о дочерней активности как часть Intent
, которую вы запускаете.
Как только дочернее действие запускается, оно получает доступ к информации, переданной ему через дополнительные функции Intent, и вызывает setResult()
, чтобы отправить информацию обратно, — вызывает finish()
, чтобы вернуться к родительскому действию.
Только когда вы возвращаетесь к родительской активности, срабатывает обратный вызов result ->
лямбда, прикрепленный к этому обратному вызову registerForActivityResult
, возвращая результат.
Вы вообще не переопределяете onActivityResult
. Вы вообще не звоните startActivityForResult
. registerForActivityResult
и вызов launch
по возвращенному ActivityResultLauncher
— это все, что вам действительно нужно сделать на стороне родительской активности.
В моем случае мой вызов startActivityForResult(intent, code); Ничего не сделал. Но я заметил, что это произошло потому, что в AndroidManifest я объявлял android:parentActivityName, поэтому действие, которое я пытался запустить, было проигнорировано, поскольку имя действия, объявленное в манифесте, было другим.
Меня немного смущает ваш поток данных между действиями. API результатов действий предназначен для возврата результатов к предыдущему действию, но вы, кажется, используете его, чтобы попытаться передать результаты в новое действие?