我在下面的manager.popbackbackstack行中遇到此错误。有办法解决这个问题吗?事情发生得很顺利。
public void updateView(Fragment fragment) {
IFragment currentFragment = (IFragment)fragment;
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment);
if(currentFragment != null)
{
if(currentFragment.isRoot())
{
manager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
else
{
fragmentTransaction.addToBackStack("test");
}
}
fragmentTransaction.commitAllowingStateLoss();
if(drawerManager.DrawerLayout != null) {
drawerManager.DrawerLayout.closeDrawer(drawerManager.DrawerList);
}
}
致命异常:java.lang.IllegalStateException:在android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2044)在android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2067)在android.support.v4.app.FragmentManagerImpl.popBackStack上无法执行此操作com.exposure.activities.EventActivity.setupEvent(EventActivity.java:204)com.exposure.activities.EventActivity.setupEvent(EventActivity.java:204)com.exposure.activities.EventActivity.getData(EventActivity.java:117)com.exposure.utilities.ActivityContainer.getData(ActivityContainer.java:83)android.os.AsyncTask.finish(AsyncTask.java:695)上的com.exposure.utilities.DataTask.onPostExecute(DataTask.java:37)上的android.os.AsyncTask.finish上的android.os.AsyncTask.onPostExecute(DataTask.java:37)上的android.os.Looper.loop(Looper.java:164)上的dispatchMessage(Handler.java:105)上的wrap1(未知源代码)android.app.ActivityThread.main(ActivityThread.java:6938)的java.lang.reflect.Method.invoke(Method.java)的com.android.internal.os.Zygote$methodAndArgscaler.run(Zygote.java:327)的com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
只需调用popBackStackImmediate(),因为常规popBackStack()是异步的。。。
对我来说,这就是检查片段管理器在popBackStack()之前是否没有保存状态
if(碎片管理器!=null
如碎片交易中所述
避免在异步回调方法内执行事务。这包括常用的方法,如AsyncTask#onPostExecute()
和LoaderManager.LoaderCallbacks#onLoadFinished()
。在这些方法中执行事务的问题在于,调用它们时,它们不知道活动生命周期的当前状态。
这似乎是您遇到的问题,因为updateView()
是从异步任务调用的,但是让我们测试一下这个假设。
下面的演示应用程序创建一个片段,模拟后台处理和模拟异步回调的回调。代码中有一个标志,mFixIt
当设置为true时会导致应用程序正常运行(而不是爆炸),当false让应用程序失败。
使用mFixIt==false。触发器是使应用程序进入停止状态的主页按钮:
以下是堆栈跟踪:
14967-15003 E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.example.illegalstatepopbackstack, PID: 14967
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2080)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2106)
at android.support.v4.app.FragmentManagerImpl.popBackStack(FragmentManager.java:832)
at com.example.illegalstatepopbackstack.MainActivity.updateView(MainActivity.java:70)
at com.example.illegalstatepopbackstack.ui.main.MainFragment$1.run(MainFragment.java:63)
at java.lang.Thread.run(Thread.java:764)
现在使用mFixIt
==true。这次的不同之处在于,当活动处于停止状态时,应用程序识别异步回调,记录已发生的情况,并在应用程序重新启动时完成处理。视觉系统只需按下home(主页)按钮并从“最近”恢复即可。应用程序只需在开始时放置片段,重新启动时会更改顶部的TextView
文本,并从后台弹出片段。
可以看出,处理按预期完成。
这是一个微不足道的例子。如果您的处理更复杂,或者您只是想要一种更正式的方式来处理这种情况,我建议您看看这个解决方案。
以下是演示应用程序的代码:
MainActivity.java
public class MainActivity extends AppCompatActivity {
// Set to true to fix the problem; false will cause the IllegalStateException
private boolean mFixIt = false;
private MainFragment mFragment;
private TextView mTextView;
private boolean mIsPaused;
private boolean mUpdateViewNeeded;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mTextView = findViewById(R.id.textView);
FragmentManager fm = getSupportFragmentManager();
if (savedInstanceState == null) {
// Create out fragment
mFragment = MainFragment.newInstance();
fm.beginTransaction()
.replace(R.id.container, mFragment)
.addToBackStack(FRAGMENT_TAG)
.commit();
} else {
// Find the restored fragment.
mFragment = (MainFragment) fm.findFragmentByTag(FRAGMENT_TAG);
}
}
@Override
protected void onStop() {
super.onStop();
// Simulate a background task that does something useful. This one just waits a few
// second then does a callback to updateView(). The activity will be fully paused by then.
mFragment.doSomethingInBackground();
mIsPaused = true;
Log.d("MainActivity","<<<< stopped");
}
@Override
protected void onStart() {
super.onStart();
mIsPaused = false;
if (mUpdateViewNeeded) {
// Execute delayed processing now that the activity is resumed.
updateView(getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG));
}
}
public void updateView(Fragment fragment) {
if (mIsPaused && mFixIt) {
// Delay processing
mUpdateViewNeeded = true;
} else {
// Do out update work. If we are paused, this will get an IllegalStateException. If
// we are resumed, this will work as intended.
mTextView.setText("Replaced...");
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
mUpdateViewNeeded = false;
}
}
public static final String FRAGMENT_TAG = "MyFragment";
}
MainFragment.java
public class MainFragment extends Fragment {
MainActivity mMainActivity;
public static MainFragment newInstance() {
return new MainFragment();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.main_fragment, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mMainActivity = (MainActivity) context;
}
@Override
public void onDetach() {
super.onDetach();
mMainActivity = null;
}
@Override
public void onStart() {
super.onStart();
}
public void doSomethingInBackground() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (mMainActivity != null) {
mMainActivity.updateView(MainFragment.this);
}
}
}).start();
}
}
main_activity.xml
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_light"
android:gravity="center"
android:text="To be replaced..."
android:textSize="36sp"
android:textStyle="bold" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" />
main_fragment.xml
<android.support.constraint.ConstraintLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_green_light"
tools:context=".ui.main.MainFragment">
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MainFragment"
android:textSize="36sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
null java.lang.IllegalStateException:在onSaveInstanceState e/androidRuntime(9008):at android.support.v4.app.fragmentManagerImpl.checkStateLoss(fragmentManager.java:1354)e/androidRuntime(9008):at androi
问题内容: 在实现一个用户可以登录的应用程序时,我会遇到以下情况:如果用户已登录,请执行该操作,否则启动结果的登录活动,如果结果为Activity.RESULT_OK,请执行该操作。 我的问题是,执行perfom的操作是显示DialogFragment,但是调用 在onActivityResult回调中引发异常: 那么我该如何解决呢?我正在考虑在此处举一个标志并在onResume中显示对话框,但我
问题内容: 我从市场上的应用程序中获取用户报告,但出现以下异常: 显然,它与FragmentManager有关,我不使用。stacktrace不显示我自己的任何类,因此我不知道发生此异常的位置以及如何防止它。 作为记录:我有一个tabhost,在每个选项卡中都有一个ActivityGroup在Activity之间切换。 问题答案: 基本上我只需要: 不要在方法上进行调用。这太糟了… 这是支持包中的
问题内容: 嗨,我用片段A,第二个片段用b。调用了b并使用了 方法,但是我第一次使用它是完美的,但是第二次使用它使应用程序崩溃,并且我的错误日志在以下:::我使用了Samsung平板电脑,但工作正常,但是Samsung core mobile崩溃了。 我的课程用于: 使用的第二个片段: 使用的第三个片段::: 问题答案: 这被称为 状态丢失 。您碰巧从AsyncTask提交FragmentTran
问题内容: 我是Android开发的新手。我有一个问题。我尝试了最后几个小时,但我无法弄清楚。如果是这样,我有一个很普遍的问题。IllegalStateException:使用ViewPager在onSaveInstanceState之后无法执行此操作,但由于缺少Android开发经验而失败。 这是代码: 这是错误: 位于android.os.Handler.dispatchMessage(Han