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();