问题
I have an app with two activities. From the main activity I start a secondary activity using startActivityForResult()
. The secondary activity returns data (in the form of an Intent
object) to the main activity. On the main activity I have a method onActivityResult()
to handle the come back from the secondary activity.
Within this onActivityResult()
method, I need to update a View
on the main activity (to reflect the new data values). I do not explicitly spawn any threads. My question is: can I directly modify the view from within onActivityResult()
method, or do I need to put an event on the UI queue to do it? To be more explicit: can I be sure that the onActivityResult()
method is on the UI thread, and in that case can I forget about the UI queue?
回答1:
Yes, you can modify the view in
onActivityResult()
. You can modify anActivity
's views anytime after you callsetContentView()
inonCreate()
, as long as you are running on the UI thread.Yes,
onActivityResult()
is called on the UI thread. This is true for all life cycle methods (onCreate()
,onResume()
, etc).
回答2:
Although onActivityResult
is on Ui thread, you may not see your UI updated when modified in onActivityResult
. I suspect the reason is redrawing of Ui elements at onResume
which forces ui elements to reset by calling resetViews()
of ActivityTransitionState
at super.onResume()
.
I faced with this issue while simply updating an EditText
inside onActivityResult
. EditText
was not updated.
The workaround is to save your data in onActivityResult
and update Ui at onResume
by setting a flag in onActivityResult
.
回答3:
The onActivityResult() is executed in the UI thread, you can modify the view on this method.
回答4:
When I try to create and show an AlertDialog on onActivityResult() coming back from making a photo, I get an "android.view.WindowLeaked" error android.view.WindowLeaked:
Activity com...MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{37ac7e30 V.E..... R.....I. 0,0-1272,584} that was originally added here
as soon as I try to show the dialog.
So I believe it's not always OK to assume that OnActivityResult() runs on the main thread.
回答5:
In Current Fragment 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 on Edittext in OnResume.
@Override
public void onResume() {
super.onResume();
mChooseBankEdittext.setText(bankName);
}
In the Target Fragment ChooseBankNameFragment
performed below onClick() in Fragment
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();
来源:https://stackoverflow.com/questions/17774176/android-ui-when-can-i-directly-modify-a-view