在 Android 上恢复 FragmentActivity 后出现“java.lang.IllegalStateException:Activity 已被销毁”

Posted

技术标签:

【中文标题】在 Android 上恢复 FragmentActivity 后出现“java.lang.IllegalStateException:Activity 已被销毁”【英文标题】:“java.lang.IllegalStateException: Activity has been destroyed” after resuming the FragmentActivity on Android 【发布时间】:2014-03-01 12:55:53 【问题描述】:

我正在使用这种方法:Separate Back Stack for each tab in android using Fragments

我正在尝试从第一个片段推送片段,在恢复 FragmentActivity 后,此操作会导致“Activity 已被销毁”错误。第一次推送片段时它工作正常,但是当我暂停(最小化应用程序)该 FragmentActivity,重新打开它然后尝试推送片段时,它会给出错误。我知道这个问题已经被问过很多次了,但我无法从中得到任何解决方案。

错误

02-05 11:51:01.889: E/AndroidRuntime(379): FATAL EXCEPTION: main
02-05 11:51:01.889: E/AndroidRuntime(379): java.lang.IllegalStateException: Activity has been destroyed
02-05 11:51:01.889: E/AndroidRuntime(379):     at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1365)
02-05 11:51:01.889: E/AndroidRuntime(379):     at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
02-05 11:51:01.889: E/AndroidRuntime(379):     at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:578)
02-05 11:51:01.889: E/AndroidRuntime(379):     at com.app.main.AppMainTabActivity.pushFragments(AppMainTabActivity.java:650)
02-05 11:51:01.889: E/AndroidRuntime(379):     at com.app.home.Home$ExpandableListAdapter$1.onClick(Home.java:530)
02-05 11:51:01.889: E/AndroidRuntime(379):     at android.view.View.performClick(View.java:2408)
02-05 11:51:01.889: E/AndroidRuntime(379):     at android.view.View$PerformClick.run(View.java:8816)
02-05 11:51:01.889: E/AndroidRuntime(379):     at android.os.Handler.handleCallback(Handler.java:587)
02-05 11:51:01.889: E/AndroidRuntime(379):     at android.os.Handler.dispatchMessage(Handler.java:92)
02-05 11:51:01.889: E/AndroidRuntime(379):     at android.os.Looper.loop(Looper.java:123)
02-05 11:51:01.889: E/AndroidRuntime(379):     at android.app.ActivityThread.main(ActivityThread.java:4627)
02-05 11:51:01.889: E/AndroidRuntime(379):     at java.lang.reflect.Method.invokeNative(Native Method)
02-05 11:51:01.889: E/AndroidRuntime(379):     at java.lang.reflect.Method.invoke(Method.java:521)
02-05 11:51:01.889: E/AndroidRuntime(379):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-05 11:51:01.889: E/AndroidRuntime(379):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-05 11:51:01.889: E/AndroidRuntime(379):     at dalvik.system.NativeStart.main(Native Method)

我单击第一个片段中的可扩展列表视图项,它会推送第二个片段。我在 BaseExpandableListAdapter 中显示错误。

AppMainFragmentActivity 中的推送和弹出方法

public void pushFragments(String tag, Fragment fragment, boolean shouldAnimate, boolean shouldAdd) 
    if (shouldAdd) 
        mStacks.get(tag).push(fragment);
    

    if (!isFinishing()) 
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction ft = manager.beginTransaction();
        if (shouldAnimate)
            ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
        ft.replace(R.id.realtabcontent, fragment);
        ft.commit();
        
    else 
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction ft = manager.beginTransaction();
        if (shouldAnimate)
            ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
        ft.replace(R.id.realtabcontent, fragment);
        ft.addToBackStack(null);
        ft.commitAllowingStateLoss();//error shows here also.
    


public void popFragments() 
    /*if (!isFinishing())  */
    Fragment fragment = mStacks.get(mCurrentTab).elementAt(mStacks.get(mCurrentTab).size() - 2);
    /*pop current fragment from stack.. */
    mStacks.get(mCurrentTab).pop();

    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
    ft.replace(R.id.realtabcontent, fragment);
    ft.commit();

首页片段

public class Firstfragment extends BaseFragment

@Override
public void onAttach(Activity activity) 
    super.onAttach(activity);


@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);



private void setupActionBar() 
    // TODO Auto-generated method stub

    actionBar = getSherlockActivity().getSupportActionBar();

    actionBar.setDisplayHomeAsUpEnabled(false);


    actionBar.setDisplayShowCustomEnabled(true);
    actionBar.setDisplayShowHomeEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    View cView = getSherlockActivity().getLayoutInflater().inflate(R.layout.actionbarbutton, null);
    final TextView cTitletext = (TextView) cView.findViewById(R.id.action_title_home);
    final ImageButton cSection_Menu = (ImageButton) cView.findViewById(R.id.imgbtn_1);

    actionBar.setCustomView(cView);
    cSection_Menu.setImageResource(R.drawable.section);
    cSection_Menu.setVisibility(View.VISIBLE);

    cTitletext.setVisibility(View.VISIBLE);


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,    Bundle savedInstanceState) 
    View view = inflater.inflate(R.layout.home_newspaper_list, container,false);
    lv = (ExpandableListView) view.findViewById(R.id.newspapers_expandable);

    setHasOptionsMenu(true);
    return view;


@Override
public void onSaveInstanceState(Bundle outState) 
    super.onSaveInstanceState(outState);
    flag = true;
    outState.putBoolean("flag", flag);


@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
    super.onCreateOptionsMenu(menu, inflater);


@Override
public void onPause() 
    super.onPause();
    flag = true;
    AppConstants.isFromHomeDetailView = false;
    index = lv.getFirstVisiblePosition();


@Override
public void onStop() 
    // TODO Auto-generated method stub
    super.onStop();


@Override
public void onResume() 
    super.onResume();
    lv.setSelectionFromTop(index, 0);

    System.out.println(" onResume Started > "+flag);
    setupActionBar();


@Override
public void onActivityCreated(Bundle savedInstanceState) 
    super.onActivityCreated(savedInstanceState);

    HashMap<String, ArrayList<HashMap<String,String>>> nlist = ma.newspaper_list;
    ArrayList<String> languagelist = ma.languagelist;

    expListAdapter = new ExpandableListAdapter(getActivity(), languagelist, nlist);

    lv.setAdapter(expListAdapter);


@Override
public boolean onOptionsItemSelected(MenuItem item) 
    return false;


public class ExpandableListAdapter extends BaseExpandableListAdapter


    /* methods for BaseExpandableListAdapterlike getchildcount() etc. */

    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) 
        View view = null;
        view.setOnClickListener(new OnClickListener() 
            @Override
            public void onClick(final View v) 
                secondfragment nl = new secondfragment ();
                mActivity.pushFragments(AppConstants.TAB_A,nl,true, true);//****error on that line after resuming activity**.**
            
        );
        return view;
    



【问题讨论】:

指向您的 mActivity 的指针是否正确更新? mActivityget 正确更新。但是commit() 推送片段的问题。 您应该检查您的 mActivity 是否处于活动状态。你能提供你的 mActivity 声明吗? 【参考方案1】:

当您的 FragmentActivity 完成时,您似乎正在提交 Fragment,这会导致预期。

我建议在这种情况下创建机制来存储Fragment 所需的信息,并且当您的FragmentActivity 处于活动状态且正在运行且未完成时,请执行Fragment 的提交。

【讨论】:

【参考方案2】:

除了写ft.commitAllowingStateLoss();,你只需要写commit();,因为ft.commitAllowingStateLoss();定义了

It is similar to commit() but allows the commit to be executed after an activity's state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.

因此,如果您在此之前销毁了您的活动,那么它总是会抛出 Activity has been destroyed 错误。

【讨论】:

以上是关于在 Android 上恢复 FragmentActivity 后出现“java.lang.IllegalStateException:Activity 已被销毁”的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 上恢复 FragmentActivity 后出现“java.lang.IllegalStateException:Activity 已被销毁”

如何在 Android 上管理从后台恢复的 Xamarin 表单应用程序?

Android Exoplayer,在屏幕旋转时恢复视频

Android - 恢复上次查看的活动

Android:恢复 singleTask 活动

Android 高版本日历恢复转轮(DatePicker)