"IllegalStateException : onSaveInstanceState 후에이 작업을 수행 할 수 없습니다."예외가 발생 함
라이브 Android 응용 프로그램이 있으며 시장에서 다음과 같은 스택 추적을 받았으며 응용 프로그램 코드에서 발생하지 않지만 응용 프로그램에서 일부 또는 다른 이벤트로 인해 발생하는 이유를 모릅니다 (가정)
Fragments를 사용하고 있지 않지만 여전히 FragmentManager에 대한 참조가 있습니다. 어떤 신체가 이런 유형의 문제를 피하기 위해 숨겨진 사실에 빛을 비출 수 있다면
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)
at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)
at android.app.Activity.onBackPressed(Activity.java:2066)
at android.app.Activity.onKeyDown(Activity.java:1962)
at android.view.KeyEvent.dispatch(KeyEvent.java:2482)
at android.app.Activity.dispatchKeyEvent(Activity.java:2274)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1668)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1720)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1258)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1668)
at android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2851)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2824)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2011)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4025)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
at dalvik.system.NativeStart.main(Native Method)
이것은 내가 지금까지 만난 가장 바보 같은 버그입니다. API <11 및 API> 11 에서 Fragment
완벽하게 작동 하는 응용 프로그램이 있습니다.Force Closing
Activity
에 대한 호출 에서 수명주기 내에서 무엇이 바뀌 었는지 알 수 saveInstance
없었지만 여기에이를 해결하는 방법이 있습니다.
@Override
protected void onSaveInstanceState(Bundle outState) {
//No call for super(). Bug on API Level > 11.
}
나는 단지 전화하지 않고 .super()
모든 것이 훌륭하게 작동합니다. 시간이 절약 되길 바랍니다.
편집 : 좀 더 연구 한 후에 이것은 지원 패키지 의 알려진 버그 입니다.
인스턴스를 저장하고 무언가를 추가 해야하는 경우 outState
Bundle
다음을 사용할 수 있습니다.
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
super.onSaveInstanceState(outState);
}
EDIT2 :Activity
백그라운드에서 거래를 마치고 거래를 시도하는 경우에도 발생할 수 있습니다 . 이를 피하려면 다음을 사용해야합니다commitAllowingStateLoss()
EDIT3 : 위의 솔루션은 내가 기억할 수있는 초기 support.v4 라이브러리의 문제를 수정했습니다. 당신은 여전히이 문제를 가지고있는 경우 그러나 당신은 반드시 도 읽을 @AlexLockwood '의 블로그 조각 거래 및 활동 상태의 손실을
블로그 게시물의 요약 (그러나 나는 그것을 읽는 것이 좋습니다) :
- NEVER의
commit()
후 거래를onPause()
사전에 벌집에, 그리고onStop()
이후 벌집에 Activity
라이프 사이클 메소드 내에서 트랜잭션을 커미트 할 때주의하십시오 . 사용onCreate()
,onResumeFragments()
및onPostResume()
- 비동기 콜백 메소드 내에서 트랜잭션을 수행하지 마십시오
commitAllowingStateLoss()
최후의 수단으로 만 사용
이 문제의 원인에 대한 Android 소스 코드를 살펴보면 FragmentManagerImpl
클래스 에서 mStateSaved 플래그 (Activity에서 사용 가능한 인스턴스)의 값이 true입니다. 호출시 백 스택이 저장 될 때 (saveAllState) true로 설정됩니다 Activity#onSaveInstanceState
. 이후 ActivityThread의 호출은 FragmentManagerImpl#noteStateNotSaved()
및 에서 사용 가능한 재설정 메소드를 사용하여이 플래그를 재설정하지 않습니다 dispatch()
.
내가 보는 방식에는 앱이 수행하고 사용하는 작업에 따라 사용 가능한 수정 사항이 있습니다.
좋은 방법
다른 무엇보다도 : 나는 Alex Lockwood 기사를 광고 할 것 입니다. 그런 다음 내가 지금까지 한 일에서 :
상태 정보를 유지할 필요가없는 프래그먼트 및 활동의 경우 commitAllowStateLoss를 호출 하십시오 . 문서에서 가져온 것 :
활동 상태가 저장된 후 커밋을 실행할 수 있습니다. 활동을 나중에 상태에서 복원해야 할 경우 커밋이 유실 될 수 있으므로 위험합니다. 따라서 UI 상태가 사용자에게 예기치 않게 변경 될 수있는 경우에만 사용해야합니다. 조각이 읽기 전용 정보를 표시하는 경우 이것이 사용하는 것이 좋습니다. 또는 편집 가능한 정보를 표시하더라도 콜백 메소드를 사용하여 편집 된 정보를 유지하십시오.
트랜잭션이 커밋 된 직후 (방금 호출
commit()
)을 (를 ) 호출합니다FragmentManager.executePendingTransactions()
.
권장하지 않는 방법 :
위에서 언급 한 Ovidiu Latcu는 전화하지 마십시오
super.onSaveInstanceState()
. 그러나 이것은 조각 상태와 함께 활동의 전체 상태를 잃을 것임을 의미합니다.재정의
onBackPressed
하고 거기에서만 호출합니다finish()
. 응용 프로그램에서 Fragments API를 사용하지 않으면 괜찮습니다. 에super.onBackPressed
대한 호출이FragmentManager#popBackStackImmediate()
있습니다.Fragments API를 모두 사용하고 있고 활동 상태가 중요 / 중요한 경우 리플렉션 API를 사용하여 호출 할 수
FragmentManagerImpl#noteStateNotSaved()
있습니다. 그러나 이것은 해킹이거나 해결 방법이라고 말할 수 있습니다. 나는 그것을 좋아하지 않지만, 사용되지 않는 코드 (TabActivity
암시 적으로LocalActivityManager
) 를 사용하는 레거시 응용 프로그램의 코드가 있기 때문에 내 경우에는 꽤 수용 가능 합니다.
다음은 리플렉션을 사용하는 코드입니다.
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
invokeFragmentManagerNoteStateNotSaved();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void invokeFragmentManagerNoteStateNotSaved() {
/**
* For post-Honeycomb devices
*/
if (Build.VERSION.SDK_INT < 11) {
return;
}
try {
Class cls = getClass();
do {
cls = cls.getSuperclass();
} while (!"Activity".equals(cls.getSimpleName()));
Field fragmentMgrField = cls.getDeclaredField("mFragments");
fragmentMgrField.setAccessible(true);
Object fragmentMgr = fragmentMgrField.get(this);
cls = fragmentMgr.getClass();
Method noteStateNotSavedMethod = cls.getDeclaredMethod("noteStateNotSaved", new Class[] {});
noteStateNotSavedMethod.invoke(fragmentMgr, new Object[] {});
Log.d("DLOutState", "Successful call for noteStateNotSaved!!!");
} catch (Exception ex) {
Log.e("DLOutState", "Exception on worka FM.noteStateNotSaved", ex);
}
}
건배!
프래그먼트 활동 onSaveInstanceState()
이 호출 된 후 프래그먼트 전환을 수행하려고하면 이러한 예외가 발생합니다 .
이런 일이 발생할 수있는 한 가지 이유 는 활동이 중지 될 때 AsyncTask
(또는 Thread
)을 실행 상태로 두는 것 입니다.
onSaveInstanceState()
시스템이 자원에 대한 활동을 재 확보하고 나중에 다시 작성하면 호출 후 전환 이 손실 될 수 있습니다.
간단히 전화 super.onPostResume ()을 당신의 조각을 표시하기 전에 또는 super.onPostResume를 호출 한 후) (onPostResume에 방법을 코드를 이동 (). 이것은 문제를 해결합니다!
dismiss()
화면이 잠기거나 비워지고 Activity + 대화 상자의 인스턴스 상태가 저장된 후 대화 상자 조각을 호출 할 때도 발생할 수 있습니다 . 이 전화를 피하려면 :
dismissAllowingStateLoss()
문자 그대로 대화 상자를 닫을 때마다 더 이상 상태에 대해 신경 쓰지 않으므로 그렇게해도 괜찮습니다. 실제로 상태를 잃지 않습니다.
짧고 효과적인 해결책 :
간단한 단계를 따르십시오 :
1 단계 : 각 조각에서 onSaveInstanceState 상태를 재정의합니다. 그리고 슈퍼 메소드를 제거하십시오.
@Override
public void onSaveInstanceState(Bundle outState) {
};
2 단계 : CommitAllowingStateLoss () 사용 commit () 대신; 조각 작업 중.
fragmentTransaction.commitAllowingStateLoss();
라이프 사이클 상태는 Android 지원 lib v26.1.0에서 시작하여 이러한 충돌을 방지하는 데 도움이 될 수 있다고 생각합니다.
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)){
// Do fragment's transaction commit
}
또는 시도해 볼 수 있습니다 :
Fragment.isStateSaved()
자세한 내용은 여기 https://developer.android.com/reference/android/support/v4/app/Fragment.html#isStateSaved ()
이것은 나를 위해 일했습니다 ... 내가 이것을 발견했습니다 ... 그것이 도움이되기를 바랍니다!
1) 글로벌 "정적"FragmentManager / FragmentTransaction이 없습니다.
2) onCreate, 항상 FragmentManager를 다시 초기화하십시오!
아래 샘플 :-
public abstract class FragmentController extends AnotherActivity{
protected FragmentManager fragmentManager;
protected FragmentTransaction fragmentTransaction;
protected Bundle mSavedInstanceState;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedInstanceState = savedInstanceState;
setDefaultFragments();
}
protected void setDefaultFragments() {
fragmentManager = getSupportFragmentManager();
//check if on orientation change.. do not re-add fragments!
if(mSavedInstanceState == null) {
//instantiate the fragment manager
fragmentTransaction = fragmentManager.beginTransaction();
//the navigation fragments
NavigationFragment navFrag = new NavigationFragment();
ToolbarFragment toolFrag = new ToolbarFragment();
fragmentTransaction.add(R.id.NavLayout, navFrag, "NavFrag");
fragmentTransaction.add(R.id.ToolbarLayout, toolFrag, "ToolFrag");
fragmentTransaction.commitAllowingStateLoss();
//add own fragment to the nav (abstract method)
setOwnFragment();
}
}
onActivityForResult () 메서드에서 조각을 표시하려고 할 때 항상 이것을 얻었습니다. 따라서 문제는 다음과 같습니다.
- 내 활동이 일시 중지되고 중지되었습니다. 즉, onSaveInstanceState ()가 이미 호출되었습니다 (Honeycomb 이전 및 Howncomb 이후 장치 모두에 대해).
- 결과가 발생하면 트랜잭션이 조각을 표시하거나 숨기도록 하여이 IllegalStateException이 발생합니다.
내가 만든 것은 다음입니다.
- 원하는 동작이 수행되었는지 확인하기위한 값 추가 (예 : camere에서 사진 찍기-isPhotoTaken)-필요한 트랜잭션 수에 따라 부울 또는 정수 값일 수 있습니다.
- 재정의 된 onResumeFragments () 메서드에서 내 값을 확인하고 조각 트랜잭션을 수행 한 후 필요했습니다. 이 경우, onResumeFragments () 메소드에서 상태가 리턴 되었기 때문에 onSaveInstanceState 후에 commit ()이 수행되지 않았습니다.
onconfigurationchanged로 문제를 해결했습니다. 요령은 명시 적으로 intent (카메라 의도 또는 다른 것)를 호출했을 때 안드로이드 활동 수명주기에 따라 다릅니다. 이 경우 활동이 일시 중지되고 onsavedInstance가 호출됩니다. 활동이 활성화 된 위치가 아닌 다른 위치로 장치를 회전시킬 때; 조각 커밋과 같은 조각 작업을 수행하면 잘못된 상태 예외가 발생합니다. 그것에 대해 많은 불만이 있습니다. 그것은 안드로이드 활동 라이프 사이클 관리 및 적절한 메소드 호출에 관한 것입니다. 이를 해결하기 위해 다음과 같이했습니다. 1-활동의 onsavedInstance 메소드를 재정의하고 현재 화면 방향 (세로 또는 가로)을 결정한 다음 활동이 일시 중지되기 전에 화면 방향을 설정하십시오. 그렇게하면 활동이 다른 활동에 의해 회전 된 경우 활동에 대한 화면 회전을 잠급니다. 2, onresume 활동 방법을 재정의하고 onsaved 메소드가 호출 된 후 회전을 올바르게 처리하도록 구성에서 한 번 더 호출하도록 방향 모드를 센서로 설정하십시오.
이 코드를 복사하여 활동에 붙여 넣어 처리 할 수 있습니다.
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Toast.makeText(this, "Activity OnResume(): Lock Screen Orientation ", Toast.LENGTH_LONG).show();
int orientation =this.getDisplayOrientation();
//Lock the screen orientation to the current display orientation : Landscape or Potrait
this.setRequestedOrientation(orientation);
}
//A method found in stackOverflow, don't remember the author, to determine the right screen orientation independently of the phone or tablet device
public int getDisplayOrientation() {
Display getOrient = getWindowManager().getDefaultDisplay();
int orientation = getOrient.getOrientation();
// Sometimes you may get undefined orientation Value is 0
// simple logic solves the problem compare the screen
// X,Y Co-ordinates and determine the Orientation in such cases
if (orientation == Configuration.ORIENTATION_UNDEFINED) {
Configuration config = getResources().getConfiguration();
orientation = config.orientation;
if (orientation == Configuration.ORIENTATION_UNDEFINED) {
// if height and widht of screen are equal then
// it is square orientation
if (getOrient.getWidth() == getOrient.getHeight()) {
orientation = Configuration.ORIENTATION_SQUARE;
} else { //if widht is less than height than it is portrait
if (getOrient.getWidth() < getOrient.getHeight()) {
orientation = Configuration.ORIENTATION_PORTRAIT;
} else { // if it is not any of the above it will defineitly be landscape
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
}
}
return orientation; // return value 1 is portrait and 2 is Landscape Mode
}
@Override
public void onResume() {
super.onResume();
Toast.makeText(this, "Activity OnResume(): Unlock Screen Orientation ", Toast.LENGTH_LONG).show();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
IllegalStateException을 얻는 것과 동일한 문제가 있었지만 commit ()에 대한 모든 호출을 commitAllowingStateLoss ()로 바꾸는 것이 도움이되지 않았습니다.
범인은 DialogFragment.show ()를 호출했습니다.
나는 그것을 둘러싸고
try {
dialog.show(transaction, "blah blah");
}
catch(IllegalStateException e) {
return;
}
그렇게 했어요 좋아, 대화 상자를 표시하지 않지만이 경우에는 괜찮습니다.
앱에서 FragmentManager.beginTransaction ()을 처음 호출했지만 commit ()을 호출 한 적이없는 유일한 곳이므로 "commit ()"을 찾을 때 찾지 못했습니다.
재미있는 점은 사용자가 절대 앱을 떠나지 않는다는 것입니다. 대신 킬러는 AdMob 전면 광고가 게재되었습니다.
그 문제에 대한 나의 해결책은
조각 추가 메소드에서 :
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
guideMapFragment = (SupportMapFragment)a.getSupportFragmentManager().findFragmentById(R.id.guideMap);
guideMap = guideMapFragment.getMap();
...
}
@Override
public void onDestroyView() {
SherlockFragmentActivity a = getSherlockActivity();
if (a != null && guideMapFragment != null) {
try {
Log.i(LOGTAG, "Removing map fragment");
a.getSupportFragmentManager().beginTransaction().remove(guideMapFragment).commit();
guideMapFragment = null;
} catch(IllegalStateException e) {
Log.i(LOGTAG, "IllegalStateException on exit");
}
}
super.onDestroyView();
}
나쁘지만 더 좋은 것을 찾지 못했습니다.
이 문제가 발생했지만이 문제는 commit 및 commitAllowStateLoss와 관련이 없다고 생각합니다.
다음 스택 추적 및 예외 메시지는 commit ()에 관한 것입니다.
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1341)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1352)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
그러나이 예외는 onBackPressed ()로 인해 발생했습니다.
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(Unknown Source)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(Unknown Source)
at android.support.v4.app.FragmentActivity.onBackPressed(Unknown Source)
모두 checkStateLoss ()에 의해 발생했습니다.
private void checkStateLoss() {
if (mStateSaved) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
if (mNoTransactionsBecause != null) {
throw new IllegalStateException(
"Can not perform this action inside of " + mNoTransactionsBecause);
}
onSaveInstanceState 다음에 mStateSaved가 적용됩니다.
이 문제는 거의 발생하지 않습니다.이 문제가 발생하지 않았습니다. 문제가 다시 발생할 수 없습니다.
다음과 같은 상황에서 발생했을 수 있습니다.
이전 키는 onSaveInstanceState 이후에 호출되지만 새 활동이 시작되기 전에 호출됩니다.
문제의 근원이 무엇인지 잘 모르겠습니다. 그래서 못생긴 방법을 사용했습니다.
@Override
public void onBackPressed() {
try{
super.onBackPressed();
}catch (IllegalStateException e){
// can output some information here
finish();
}
}
내 앱에서 같은 문제가 있습니다. 이 문제 super.onBackPressed();
는 이전 클래스를 호출하고 commitAllowingStateLoss()
해당 클래스로 현재 클래스를 호출하여 해결되었습니다 .
사용자가 새 방향과 관련된 리소스를로드 할 수 있도록 화면을 회전하면 onSaveInstance가 호출됩니다.
이 사용자가 화면을 회전 한 후 뒤로 버튼을 누르면 가능할 수 있습니다 (이 사용자가 앱을 사용하는 동안 휴대 전화를 비틀었을 수도 있기 때문에)
http://chris-alexander.co.uk/on-engineering/dev/android-fragments-within-fragments/를 읽으십시오
조. fragment.isResumed () 검사는 onSaveInstanceState 메소드를 사용하지 않고 onDestroyView에서 도움이됩니다.
나와 같은 문제가 있으며 하루 종일 모든 기사, 블로그 및 stackoverflow를 분석 한 후 간단한 해결책을 찾았습니다. savedInstanceState를 전혀 사용하지 마십시오. 한 줄의 코드가있는 조건입니다. 조각 코드에서 :
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
.....
이것은 조각을로드하려고하지만 활동이 상태를 onPause ()로 변경 될 때마다 발생합니다. 예를 들어 데이터를 가져 와서 활동에로드하려고하지만 사용자가 버튼을 클릭 할 때까지 다음 활동으로 옮겼습니다.
두 가지 방법으로이 문제를 해결할 수 있습니다
transaction.commit () 대신 transaction.commitAllowingStateLoss ()를 사용하여 조각을로드 할 수 있지만 수행 된 커밋 작업이 손실 될 수 있습니다.
또는
단편을로드 할 때 활동이 재개되고 일시 정지 상태가 아닌지 확인하십시오. 부울을 작성하고 활동이 onPause () 상태가 아닌지 확인하십시오.
@Override
public void onResume() {
super.onResume();
mIsResumed = true;
}
@Override
public void onPause() {
mIsResumed = false;
super.onPause();
}
그런 다음 조각을로드하는 동안 활동이 있는지 확인하고 활동이 포 그라운드 인 경우에만로드하십시오.
if(mIsResumed){
//load the fragment
}
@gunar에게 감사하지만 더 좋은 방법이 있다고 생각합니다.
의사에 따르면 :
* If you are committing a single transaction that does not modify the * fragment back stack, strongly consider using * {@link FragmentTransaction#commitNow()} instead. This can help avoid * unwanted side effects when other code in your app has pending committed * transactions that expect different timing. * * @return Returns true if there were any pending transactions to be * executed. */ public abstract boolean executePendingTransactions();
따라서 다음 commitNow
을 교체하십시오.
fragmentTransaction.commit();
FragmentManager.executePendingTransactions()
글쎄, 성공하지 않고 위의 모든 솔루션을 시도한 후에 (기본적으로 나는 거래가 없기 때문에).
필자의 경우 FragmentManager를 요청할 때 때때로 회전시 AlertDialogs 및 ProgressDialog를 조각으로 사용하여 오류가 발생합니다.
비슷한 많은 게시물을 혼합하는 해결 방법을 찾았습니다.
FragmentActivity (이 경우 GenericActivity라고 함)에서 수행되는 3 단계 솔루션입니다.
private static WeakReference<GenericActivity> activity = null; //To avoid bug for fragments: Step 1 of 3
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//To avoid bug for fragments: Step 2 of 3
activity = new WeakReference<GenericActivity>(this);
}
@Override
public FragmentManager getSupportFragmentManager(){
//To avoid bug for fragments: Step 3 of 3
if (this == activity.get()) {
return super.getSupportFragmentManager();
}
return activity.get().getSupportFragmentManager();
}
하나의 조각에서 startactivity를 사용하면이 예외가 발생합니다.
startactivityforresult를 사용하도록 변경하면 예외가 사라집니다. :)
그래서 그것을 고치는 쉬운 방법은 startActivityForResult API를 사용하는 것입니다 :)
지도 조각 활동에서 인 텐트 선택기를 취소하기 위해 뒤로 버튼을 누를 때이 예외가 발생했습니다. onResume () 코드를 조각을 초기화하고 트랜잭션을 커밋하는 코드를 onStart ()로 바꿔서이 문제를 해결했으며 앱이 정상적으로 작동합니다. 도움이 되길 바랍니다.
이것은 Android 4.2 및 지원 라이브러리의 소스에서도 수정되었습니다. [*]
원인 및 해결 방법에 대한 자세한 내용은 Google 버그 보고서를 참조하십시오 : http://code.google.com/p/android/issues/detail?id=19917
지원 라이브러리를 사용하는 경우이 버그에 대해 걱정할 필요가 없습니다 (오랫 동안) [*]. 그러나 API를 직접 사용하고 (즉, 지원 라이브러리의 FragmentManager를 사용하지 않음) Android 4.2 미만의 API를 대상으로하는 경우 해결 방법 중 하나를 시도해야합니다.
[*] 작성 당시 Android SDK Manager는 여전히이 버그가있는 이전 버전을 배포하고 있습니다.
편집 나는이 답변을 다운 투표 한 사람을 어떻게 든 혼란스럽게했기 때문에 여기에 약간의 설명을 추가 할 것입니다.
있습니다 이 예외가 발생 될 수 있습니다 여러 가지 (그러나 관련) 상황 . 위의 답변은 문제에서 논의 된 특정 인스턴스, 즉 이후 수정 된 Android의 버그를 말합니다. 다른 이유로이 예외가 발생하면 (조각 상태가 저장된 후)하지 말아야 할 때 조각을 추가 / 제거하기 때문입니다. 이러한 상황에 처한 경우 " 중첩 된 조각-IllegalStateException"onSaveInstanceState 후에이 작업을 수행 할 수 없음 " "을 사용할 수 있습니다.
약간의 연구를 한 후에이 문제에 대한 해결책은 조각 이력서에서 커밋을 수행하는 것입니다.
출처 : https://wenchaojames.wordpress.com/2013/01/12/illegalstateexception-from-onactivityresult/
내 유스 케이스 : 리스너를 조각으로 사용하여 어떤 일이 발생했음을 활동에 알 렸습니다. 콜백 메소드에서 새로운 조각 커밋을 수행했습니다. 처음에는 완벽하게 작동합니다. 그러나 방향 변경시 활동은 저장된 인스턴스 상태로 다시 작성됩니다. 이 경우 프래그먼트가 다시 생성되지 않으면 프래그먼트에 오래된 파괴 된 리스너가 있음을 의미합니다. 어떤 식 으로든 콜백 메소드가 작동하면 트리거됩니다. 문제를 일으키는 활동을 파괴합니다. 해결책은 현재 라이브 활동으로 리스너를 단편으로 재설정하는 것입니다. 이것은 문제를 해결합니다.
내가 찾은 것은 다른 앱이 대화 상자 유형이고 터치가 백그라운드 앱으로 전송되도록 허용하면 거의 모든 백그라운드 앱 이이 오류와 충돌한다는 것입니다. 인스턴스가 저장되거나 복원 된 경우 트랜잭션이 수행 될 때마다 확인해야한다고 생각합니다.
내 경우에는 동일한 오류 예외가 발생하여 "onBackPressed ()"를 실행 가능 파일에 넣습니다 (모든보기를 사용할 수 있음).
myView.post(new Runnable() {
@Override
public void run() {
onBackPressed()
}
});
이유를 이해하지 못하지만 작동합니다!
당신은 fragmentManager.popBackStackImmediate (); 활동이 일시 중지 된 경우 활동이 완료되지 않았지만 일시 정지되고 포 그라운드가 아닙니다. popBackStackImmediate () 전에 활동이 일시 중지되었는지 여부를 확인해야합니다.
나는 매우 흥미로운 것을 발견했다. 내 앱에는 휴대 전화 갤러리를 열 수있는 옵션이 있으며 장치는 사용할 앱을 묻습니다. 대화 상자에서 회색 영역을 클릭하면이 문제가 발생했습니다. 내 활동이 onPause, onSaveInstanceState에서 onResume으로 돌아가는 방식을 알았지 만 onCreateView를 방문하지 않습니다. onResume에서 거래를하고 있습니다. 그래서 내가 한 일은 Pause에서 부정되고 있지만 onCreateView에서 true 인 플래그를 설정하는 것입니다. 플래그가 onResume 인 경우 onCommit을 수행하고 그렇지 않으면 commitAllowingStateLoss를 수행하십시오. 계속해서 많은 시간을 허비 할 수 있었지만 수명주기를 확인하고 싶었습니다. sdkversion 23 인 장치가 있는데이 문제가 발생하지 않지만 21 인 또 다른 장치가 있는데 거기에 있습니다.
popBackStackImmediate 전에 FragmentActivity.onStart를 사용할 수 있습니다
이처럼 :
public void backStackFragment() {
this.start();
getFragmentManager().popBackStackImmediate();
}
public void start(){
FragmentActivity a = getActivity();
if(a instanceof DepositPlanPadActivity){
((DepositPlanPadActivity)a).onStart();
}
if(a instanceof SmallChangePlanPad){
((SmallChangePlanPad)a).onStart();
}
if(a instanceof UserCenterActivity){
((UserCenterActivity)a).onStart();
}
}
http://jorryliu.blogspot.com/2014/09/illegalstateexception-can-not-perform.html
'Programing' 카테고리의 다른 글
수평 및 수직 요소를 중심에 배치하는 방법 (0) | 2020.03.02 |
---|---|
자식 모듈을 하위 모듈 해제 (0) | 2020.03.01 |
OPTIONS 요청이 전송되는 이유는 무엇이며 비활성화 할 수 있습니까? (0) | 2020.03.01 |
다른 자바 스크립트 함수로 인수 전달하기 (0) | 2020.03.01 |
C로 iOS 앱을 작성하는 방법 (0) | 2020.03.01 |