Android UI: когда я могу напрямую изменить представление?
У меня есть приложение с двумя действиями. Из основного действия я начинаю вторичную деятельность с помощью startActivityForResult()
. Вторичная активность возвращает данные (в виде объекта Intent
) в основное действие. В основном действии у меня есть метод onActivityResult()
, чтобы обработать возврат из вторичной активности.
В рамках этого метода onActivityResult()
мне нужно обновить View
в основном действии (чтобы отразить новые значения данных). Я явно не создаю нити. Мой вопрос: могу ли я напрямую изменить представление из метода onActivityResult()
, или мне нужно поместить событие в очередь пользовательского интерфейса, чтобы сделать это? Чтобы быть более явным: могу ли я быть уверенным, что метод onActivityResult()
находится в потоке пользовательского интерфейса, и в таком случае я могу забыть о очереди UI?
Ответы
Ответ 1
-
Да, вы можете изменить вид в onActivityResult()
. Вы можете изменять представления Activity
в любое время после вызова setContentView()
в onCreate()
, если вы работаете в потоке пользовательского интерфейса.
-
Да, onActivityResult()
вызывается в потоке пользовательского интерфейса. Это справедливо для всех методов жизненного цикла (onCreate()
, onResume()
и т.д.).
Ответ 2
Хотя onActivityResult
находится в потоке Ui, вы не можете обновлять свой интерфейс после изменения в onActivityResult
. Я подозреваю, что причиной является перерисовка элементов Ui в onResume
, которая заставляет ui элементы reset, вызывая resetViews()
of ActivityTransitionState
в super.onResume()
.
Я столкнулся с этой проблемой, просто обновив EditText
внутри onActivityResult
. EditText
не обновлялся.
Обходной путь - сохранить ваши данные в onActivityResult
и обновить Ui на onResume
, установив флаг в onActivityResult
.
Ответ 3
Функция onActivityResult() выполняется в потоке пользовательского интерфейса, вы можете изменить представление этого метода.
Ответ 4
Когда я пытаюсь создать и показать AlertDialog на onActivityResult(), возвращающемся с момента создания фотографии, я получаю сообщение об ошибке "android.view.WindowLeaked"
android.view.WindowLeaked:
Activity com... MainActivity просочилось окно com.android.internal.policy.impl.PhoneWindow $DecorView {37ac7e30 V.E..... R..... I. 0,0-1272,584}, который был первоначально добавлен здесь.
как только я попытаюсь показать диалог.
Поэтому я считаю, что не всегда хорошо предположить, что OnActivityResult() работает в основном потоке.
Ответ 5
В текущем фрагменте AddNewAccountFragment
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == Constants.CHOOSE_BANK_REQUEST_CODE) {
bankName = data.getStringExtra("BANK_NAME");
if (!TextUtils.isEmpty(bankName)) {
mChooseBankEdittext.setText(bankName);
mReceivedBankName = bankName;
}
}
}
}
// if sending data from next fragment to previous fragment using OnActivityResult.
setText на Edittext в OnResume.
@Override
public void onResume() {
super.onResume();
mChooseBankEdittext.setText(bankName);
}
В целевом фрагменте ВыбратьBankNameFragment
выполняется ниже onClick() в фрагменте
Intent intent = new Intent(getActivity(), AddNewAccountFragment.class);
intent.putExtra("BANK_NAME", bankName);
if (getFragmentManager().findFragmentByTag("AddNewAccountFragment") != null)
getFragmentManager().findFragmentByTag("AddNewAccountFragment").onActivityResult(Constants.CHOOSE_BANK_REQUEST_CODE, RESULT_OK, intent);
getActivity().getSupportFragmentManager().popBackStack();