Android 如何修复:启动的活动完成时,onResume在onActivityResult之前和之后都被调用
我正在尝试使用调用活动Android 如何修复:启动的活动完成时,onResume在onActivityResult之前和之后都被调用,android,fragment,onactivityresult,onresume,fragment-lifecycle,Android,Fragment,Onactivityresult,Onresume,Fragment Lifecycle,我正在尝试使用调用活动 startActivityForResult() 从一块碎片上。这个活动基本上做了一些事情,然后返回结果,但是发生了什么,这真的很奇怪,在被调用的活动完成后,片段调用onStart,然后onResume,然后onActivityResult,然后再次onResume,我不明白为什么。这引起了很多麻烦 代码如下: Class extends ListFragment { ... @Override public void onResume() {
startActivityForResult()
从一块碎片上。这个活动基本上做了一些事情,然后返回结果,但是发生了什么,这真的很奇怪,在被调用的活动完成后,片段调用onStart,然后onResume,然后onActivityResult,然后再次onResume,我不明白为什么。这引起了很多麻烦
代码如下:
Class extends ListFragment {
...
@Override
public void onResume() {
Log.i(TAG_LOG, "onResume");
SharedPreferences pref = getActivity().getSharedPreferences(PreferenceKeys.PREF_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
long timePassed;
// goes here if the trial time has expired
if ((pref.getBoolean(PreferenceKeys.TRIAL_DONE, false) && pref.getString(PreferenceKeys.USERNAME, "").equals("")) ||
(!pref.getBoolean(PreferenceKeys.TRIAL, false) && pref.getString(PreferenceKeys.USERNAME, "").equals(""))) {
Log.i(TAG_LOG, "onResume-first if");
if (pref.getBoolean(PreferenceKeys.ON_RESUME_CALL, true)) {
Log.i(TAG_LOG, "onResume-first if-onResumeCall");
editor.putBoolean(PreferenceKeys.ON_RESUME_CALL, false);
Intent intent = new Intent(getActivity(), LoginRegisterActivity.class);
if (!pref.getBoolean(PreferenceKeys.TRIAL_DONE, false)) {
intent.putExtra("showTrialButton", true);
}
startActivityForResult(intent, REQUEST_LOGIN_REGISTER);
}
} else if (!pref.getBoolean(PreferenceKeys.TRIAL_DONE, false) &&
mResponseReceiver == null &&
(timePassed = pref.getLong(PreferenceKeys.TRIAL_STARTING_TIME, 0)) != 0) {
Log.i(TAG_LOG, "sono dentroooooo");
//this happens when the application has been force stopped,
//since the receiver would never be notified and the trial would never end
if ((System.currentTimeMillis() - timePassed) >= (30 * 60 * 1000)) {
if (onUserActionListener != null) {
onUserActionListener.onTrialEnded();
}
} else {
if (onUserActionListener != null) {
onUserActionListener.onTrialStarted();
}
}
}
super.onResume();
}
...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG_LOG, "onActivityResult");
if (requestCode == REQUEST_LOGIN_REGISTER) {
if(resultCode == Activity.RESULT_OK){
String username;
String password;
SharedPreferences preferences = getActivity().getSharedPreferences(PreferenceKeys.PREF_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
if ((!data.hasExtra(PreferenceKeys.USERNAME))) {
if(data.getBooleanExtra(PreferenceKeys.TRIAL, false) &&
!preferences.getBoolean(PreferenceKeys.TRIAL, false)) {
editor.putBoolean(PreferenceKeys.ON_RESUME_CALL, true).apply();
// this is used to show the log in button while mode is trial
onUserActionListener.onTrialStarted();
}
} else {
// TODO: manage the connection with the server
username = data.getStringExtra(PreferenceKeys.USERNAME);
password = data.getStringExtra(PreferenceKeys.PASSWORD);
onUserActionListener.onUserConnected(username, password);
}
}
if (resultCode == Activity.RESULT_CANCELED) {
//Write your code if there's no result
}
}
}
...
}
public class LoginRegisterActivity extends Activity {
private Button trialButton;
public static final int REQUEST_CODE_REGISTER = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_register);
final Intent intent = new Intent();
if (getIntent().hasExtra("showTrialButton") && getIntent().getExtras().getBoolean("showTrialButton")) {
findViewById(R.id.trial_button).setVisibility(View.VISIBLE);
}
trialButton = findViewById(R.id.trial_button);
trialButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent.putExtra(PreferenceKeys.TRIAL, true);
setResult(RESULT_OK, intent);
finish();
}
});
}
}
这是日志打印的内容
启动
恢复
先恢复
if onResume首先if onResume调用
onActivityResult
恢复
我就是不明白。有人知道如何解决这个问题吗?如果是这样的话,就让它去吧,不要弄乱操作系统,只是为了停止制造问题,你可以像这样为结果数据制作一个包装器:
public class MyDataWrapper<T> {
private T t;
private boolean dataHandled = false;
public MyDataWrapper(){}
public MyDataWrapper(T t){
this.t = t;
}
public T getData(){
dataHandled = true;
return t;
}
public void setData(T t){
if(this.t != t){
this.t = t;
dataHandled = false
}
}
public boolean isDataHandled(){
return dataHandled;
}
}
class MyFragment extends ListFragment {
private MyDataWrapper<MyData> myDataWrapper = new MyDataWrapper<>();
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
if (/* all conditions are right */){
myDataWrapper.setData(/* the data */);
}
}
@Override
public void onResume(){
if (!myDataWrapper.isDataHandled()){
// do the work
} else {
// data handled so there is no need to handle it again
}
}
}
公共类MyDataWrapper{
私人T;
私有布尔dataHandled=false;
公共MyDataWrapper(){}
公共MyDataWrapper(T){
t=t;
}
公共T getData(){
dataHandled=true;
返回t;
}
公共无效设置数据(T){
if(this.t!=t){
t=t;
dataHandled=false
}
}
公共布尔值isDataHandled(){
已处理的返回数据;
}
}
在你的片段中,你可以这样做:
public class MyDataWrapper<T> {
private T t;
private boolean dataHandled = false;
public MyDataWrapper(){}
public MyDataWrapper(T t){
this.t = t;
}
public T getData(){
dataHandled = true;
return t;
}
public void setData(T t){
if(this.t != t){
this.t = t;
dataHandled = false
}
}
public boolean isDataHandled(){
return dataHandled;
}
}
class MyFragment extends ListFragment {
private MyDataWrapper<MyData> myDataWrapper = new MyDataWrapper<>();
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
if (/* all conditions are right */){
myDataWrapper.setData(/* the data */);
}
}
@Override
public void onResume(){
if (!myDataWrapper.isDataHandled()){
// do the work
} else {
// data handled so there is no need to handle it again
}
}
}
类MyFragment扩展了ListFragment{
私有MyDataWrapper MyDataWrapper=新MyDataWrapper();
@凌驾
ActivityResult上的公共void(int请求代码、int结果代码、意图数据){
如果(/*所有条件都正确*/){
setData(/*数据*/);
}
}
@凌驾
恢复时公开作废(){
如果(!myDataWrapper.isDataHandled()){
//做这项工作
}否则{
//已处理数据,因此无需再次处理
}
}
}
如果您有两个片段,请尝试将hashCode()添加到日志中。尝试后,它会给出相同的hashCode,但感谢您的回复