developer tip

“Failure Delivering Result”-onActivityForResult

optionbox 2020. 10. 25. 12:06
반응형

“Failure Delivering Result”-onActivityForResult


나는이 LoginActivity(사용자가 로그인을). 기본적으로 Activity대화와 같은 테마를 가진 자체 입니다 (대화 상자처럼 표시됨). 위에 나타납니다 SherlockFragmentActivity. 내가 원하는 것은 : 성공적인 로그인이 있으면 FragmentTransaction보기를 업데이트 할 두 개의가 있어야합니다 . 다음은 코드입니다.

에서 LoginActivity로그인에 성공하면

setResult(1, new Intent());

에서 SherlockFragmentActivity:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == 1) {
        LoggedStatus = PrefActivity.getUserLoggedInStatus(this);
        FragmentTransaction t = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction();
        SherlockListFragment mFrag = new MasterFragment();
        t.replace(R.id.menu_frame, mFrag);
        t.commit();

        // Set up Main Screen
        FragmentTransaction t2 = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction();
        SherlockListFragment mainFrag = new FeaturedFragment();
        t2.replace(R.id.main_frag, mainFrag);
        t2.commit();
    }
}

다음 LogCat과 함께 첫 번째 커밋에서 충돌합니다.

E/AndroidRuntime(32072): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
E/AndroidRuntime(32072):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
E/AndroidRuntime(32072):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
E/AndroidRuntime(32072):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
E/AndroidRuntime(32072):    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
E/AndroidRuntime(32072):    at com.kickinglettuce.rate_this.MainFragmentActivity.onActivityResult(MainFragmentActivity.java:243)
E/AndroidRuntime(32072):    at android.app.Activity.dispatchActivityResult(Activity.java:5293)
E/AndroidRuntime(32072):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3315)

우선, 자세한 내용은 블로그 게시물읽어야 합니다 (이 예외가 발생하는 이유와이를 방지하기 위해 할 수있는 작업에 대해 설명합니다).

전화 commitAllowingStateLoss()는 수정 이라기보다 해킹에 가깝습니다. 상태 손실은 나쁘고 어떤 대가를 치르더라도 피해야합니다. onActivityResult()호출 되는 시점 에 활동 / 조각의 상태가 아직 복원되지 않았을 수 있으므로이 시간 동안 발생하는 모든 트랜잭션은 결과적으로 손실됩니다. 이것은 해결해야 할 매우 중요한 버그입니다! (버그 Activity는 시스템에 의해 사망 ​​한 후 다시 돌아올 때만 발생 합니다. 장치에있는 메모리 양에 따라 가끔 드물게 발생할 수 있습니다. 따라서 이런 종류의 버그는 테스트하는 동안 잡기 매우 쉽습니다).

onPostResume()대신 트랜잭션을 이동해보십시오 ( onPostResume()항상 이후에 호출 onResume()되고 onResume()항상 이후에 호출 됨 onActivityResult()).

private boolean mReturningWithResult = false;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mReturningWithResult = true;
}

@Override
protected void onPostResume() {
    super.onPostResume();
    if (mReturningWithResult) {
        // Commit your transactions here.
    }
    // Reset the boolean flag back to false for next time.
    mReturningWithResult = false;
}

이것은 조금 이상한 것 같다,하지만 이런 종류의 일을하는 것은 보장 할 필요가 수도 FragmentTransaction의 항상 최선을 다하고 있습니다 Activity '(의 상태를 원래 상태로 복원되었습니다 onPostResume()애프터 호출 할 보장 Activity의 상태가 복원되었습니다)' .


이것은 @Alex Lockwood 답변과 유사하지만 다음을 사용합니다 Runnable.

private Runnable mOnActivityResultTask;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mOnActivityResultTask = new Runnable() {
        @Override
        public void run() {
            // Your code here
        }
    }
}

@Override
protected void onPostResume() {
    super.onPostResume();
    if (mOnActivityResultTask != null) {
        mOnActivityResultTask.run();
        mOnActivityResultTask = null;
    }
}

람다 와 함께 Android 3.0 이상을 실행하는 경우 다음을 사용하십시오.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mOnActivityResultTask = () -> {
        // Your code here
    }
}

ft.commitAllowingStateLoss()이 문제를 해결하는 데 사용할 수 있습니다 .

이유 : 귀하의 ft.commit()방법이 onSaveInstanceState.


your logcat clearly says: "Can not perform this action after onSaveInstanceState" -- your Activity is already dead at that point and could not return any results.

just move:

Intent in = new Intent();
setResult(1, in);

to the place in your Activity where it's still alive, and everything will be fine. and don't forget to finish() your Activity to deliver the result.


In my Case I faced the same issues Because of the Following

public void onBackPressed() {
    super.onBackPressed();
    setIntents();

}


private void setIntents(){
    Intent searchConstaints=new Intent();
    searchConstaints.putExtra("min",20);
    searchConstaints.putExtra("max",80);
    setResult(101,searchConstaints);
    finish();
}

Solved by re-arranging the function Calls within onBackPressed()

public void onBackPressed() {

    setIntents();
    super.onBackPressed();

}

참고URL : https://stackoverflow.com/questions/16265733/failure-delivering-result-onactivityforresult

반응형