【问题标题】:App crashes when started again for a second time再次启动时应用程序崩溃
【发布时间】:2012-08-16 22:46:34
【问题描述】:

我目前正在将一个 Iphone 应用程序移植到 Android,由于我不知道 Fragment 的线索,我想我会尝试使用它们,所以我创建了几个类(一个用于呈现给用户的每个视图,所有扩展基类 Fragment)以及各自的 xml 布局。下面是启动时显示的片段的代码。我为每个片段使用一个单例。

public class FragWelcome extends Fragment {

private static FragWelcome _fs;

OnClickListener mListener;

public FragWelcome() {}

public static FragWelcome getFrag() {
    if(FragWelcome._fs==null) _fs=new FragWelcome();
    return _fs;
}

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

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

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnClickListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement OnClickListener");
    }
}

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  View v = inflater.inflate(R.layout.frag_welcome, container, false);
  ((Button)v.findViewById(R.id.btnCreateNewList)).setOnClickListener(mListener);
  ((Button)v.findViewById(R.id.btnEditOldList)).setOnClickListener(mListener);
  return v;
}
}

然后我的 Fragment Manager 类包含以下方法:

    public void addFragment(int container, Fragment f,int fadein,int fadeout, boolean addtobackstack,String tag) {

        this._currentFragment=f;
        this._fragTrans=this._fragMan.beginTransaction();
        this._fragTrans.setCustomAnimations(fadein, fadeout);
        this._fragTrans.add(container, f ,tag);
        if(addtobackstack) this._fragTrans.addToBackStack(tag);
        this._fragTrans.commit();

}
public void replaceFragment(int container, Fragment f,int fadein,int fadeout, boolean addtobackstack,String tag) {

        this._currentFragment=f;
        this._fragTrans=this._fragMan.beginTransaction();
        this._fragTrans.setCustomAnimations(fadein, fadeout);
        this._fragTrans.replace(container, f ,tag);
        if(addtobackstack) this._fragTrans.addToBackStack(tag);
        this._fragTrans.commit();

}

这是我的主要活动类 AC_Main 的 onCreate 方法。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ac_main);
    this.setTitle("Willkommen");

    FragMan.getSharedFragMan(this).addFragment(R.id.llMain,FragWelcome.getFrag(),R.animator.fade_in,R.animator.fade_out,false,"frag_welcome");  

}

我能说什么......一切都按预期工作,非常好。完全没有错误...只要我不尝试第二次启动应用程序。

08-21 16:27:18.278: D/AndroidRuntime(21576): Shutting down VM
08-21 16:27:18.278: W/dalvikvm(21576): threadid=1: thread exiting with uncaught exception (group=0x40c351f8)
08-21 16:27:18.283: E/AndroidRuntime(21576): FATAL EXCEPTION: main
08-21 16:27:18.283: E/AndroidRuntime(21576): java.lang.RuntimeException: Unable to start     activity ComponentInfo{de.lochmann.einkaufsliste/de.lochmann.einkaufsliste.AC_Main}: j     java.lang.IllegalStateException: Activity has been destroyed
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1968)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1993)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.ActivityThread.access$600(ActivityThread.java:127)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1159)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.os.Looper.loop(Looper.java:137)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.ActivityThread.main(ActivityThread.java:4507)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at java.lang.reflect.Method.invokeNative(Native Method)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at java.lang.reflect.Method.invoke(Method.java:511)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at dalvik.system.NativeStart.main(Native Method)
08-21 16:27:18.283: E/AndroidRuntime(21576): Caused by: java.lang.IllegalStateException: Activity has been destroyed
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1280)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.BackStackRecord.commit(BackStackRecord.java:525)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at de.lochmann.einkaufsliste.FragMan.addFragment(FragMan.java:41)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at de.lochmann.einkaufsliste.AC_Main.onCreate(AC_Main.java:124)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.Activity.performCreate(Activity.java:4465)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1932)
08-21 16:27:18.283: E/AndroidRuntime(21576):    ... 11 more

同样,当我从 Eclipse 启动应用程序时,一切正常,应用程序完全稳定,直到我按下我的 Android 设备(三星 Galaxy S2)的主页按钮并返回我的应用程序。当我尝试再次启动应用程序时,它会因上述错误而崩溃。任务管理器说它不再在后台运行。 所以我的问题是......我做错了什么,有人有你自己的想法或经验吗?非常感谢。

我刚刚发现如果我的应用程序在第二次崩溃并且我的设备告诉我它停止了应用程序,我可以在第三次尝试再次正常运行该应用程序。也许它仍然在后台,碎片正在造成麻烦......!?

在我实现每个生命周期方法并调用所有超级方法之后编辑,新的 LogCat 输出。

08-21 17:17:09.043: I/dalvikvm(25725): Turning on JNI app bug workarounds for target SDK version 10...
08-21 17:17:09.108: I/Activity(25725): onCreate called
08-21 17:17:09.108: I/FragWelcome(25725): onAttach called
08-21 17:17:09.108: I/FragWelcome(25725): onCreate called
08-21 17:17:09.123: D/dalvikvm(25725): GC_FOR_ALLOC freed 86K, 3% free 8909K/9091K, paused 13ms
08-21 17:17:09.128: I/dalvikvm-heap(25725): Grow heap (frag case) to 11.061MB for 2432016-byte allocation
08-21 17:17:09.148: D/dalvikvm(25725): GC_CONCURRENT freed 1K, 3% free 11282K/11527K, paused 1ms+1ms
08-21 17:17:09.203: D/dalvikvm(25725): GC_FOR_ALLOC freed 0K, 3% free 11283K/11527K, paused 11ms
08-21 17:17:09.208: I/dalvikvm-heap(25725): Grow heap (frag case) to 16.278MB for 5472016-byte allocation
08-21 17:17:09.228: D/dalvikvm(25725): GC_CONCURRENT freed 0K, 2% free 16626K/16903K, paused 1ms+2ms
08-21 17:17:09.318: I/FragWelcome(25725): onCreateView called
08-21 17:17:09.318: I/FragWelcome(25725): onActivityCreated called
08-21 17:17:09.323: I/Activity(25725): onStart called
08-21 17:17:09.323: I/FragWelcome(25725): onStart called
08-21 17:17:09.323: I/Activity(25725): onResume called
08-21 17:17:09.323: I/FragWelcome(25725): onResume called
08-21 17:17:09.503: D/CLIPBOARD(25725): Hide Clipboard dialog at Starting input: finished by someone else... !
08-21 17:17:21.258: I/FragWelcome(25725): onPause called
08-21 17:17:21.258: I/Activity(25725): onPause called
08-21 17:17:21.438: D/CLIPBOARD(25725): Hide Clipboard dialog at Starting input: finished by someone else... !
08-21 17:17:21.908: I/FragWelcome(25725): onStop called
08-21 17:17:21.908: I/Activity(25725): onStop called
08-21 17:17:21.908: I/FragWelcome(25725): onDestroyView called
08-21 17:17:21.908: I/FragWelcome(25725): onDestroy called
08-21 17:17:21.913: I/FragWelcome(25725): onDetach called
08-21 17:17:21.913: I/Activity(25725): onDestroy called
08-21 17:17:32.833: I/Activity(25725): onCreate called
08-21 17:17:32.833: D/AndroidRuntime(25725): Shutting down VM
08-21 17:17:32.833: W/dalvikvm(25725): threadid=1: thread exiting with uncaught exception (group=0x40c351f8)
08-21 17:17:32.838: E/AndroidRuntime(25725): FATAL EXCEPTION: main
08-21 17:17:32.838: E/AndroidRuntime(25725): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.lochmann.einkaufsliste/de.lochmann.einkaufsliste.AC_Main}: java.lang.IllegalStateException: Activity has been destroyed
08-21 17:17:32.838: E/AndroidRuntime(25725):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1968)
08-21 17:17:32.838: E/AndroidRuntime(25725):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1993)
08-21 17:17:32.838: E/AndroidRuntime(25725):    at android.app.ActivityThread.access$600(ActivityThread.java:127)

我从以前的 logcat 中读到的是 backstackrecord.commit 的一些问题......有人知道吗?

08-21 16:27:18.283: E/AndroidRuntime(21576): Caused by: java.lang.IllegalStateException: Activity has been destroyed
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1280)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at android.app.BackStackRecord.commit(BackStackRecord.java:525)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at de.lochmann.einkaufsliste.FragMan.addFragment(FragMan.java:41)
08-21 16:27:18.283: E/AndroidRuntime(21576):    at de.lochmann.einkaufsliste.AC_Main.onCreate(AC_Main.java:124)

【问题讨论】:

  • 首先,我建议不要保留对 Fragment 的静态引用,因为在重建类时它可能是空的。片段由 Android 操作系统内部处理。
  • 我为每个片段使用一个单例,例如 public static FragWelcome getFrag() { if(FragWelcome._fs==null) _fs=new FragWelcome();返回_fs; }。如果片段被销毁,它会再次被创建。
  • 是的,但是可以清除该引用,并且您将创建第二个引用,而第一个引用仍然存在。如果你真的想创建一个单例,那么你需要应用一个标签或 ID 并使用getFragmentById()getFragmentByTag()。如果它返回 null,则创建一个新的。否则使用旧的。

标签: android exception android-fragments illegalstateexception


【解决方案1】:

试试这个:

private void setFragmentToTop(String tag) {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);

        Fragment fragment = fm.findFragmentByTag(tag);
        if (fragment == null) {
            if (tag.equals(FragmentOne.TAG)) {
                fragment = FragmentOne.newInstance();
            }
            else if (tag.equals(FragmentTwo.TAG)) {
                fragment = FragmentTwo.newInstance();
            }
        }
        ft.replace(R.id.layoutContent, fragment, 
                tag);
        ft.commit();    

    }

【讨论】:

    【解决方案2】:

    我也有同样的问题,终于找到解决办法了987654321@.

    所以,当应用程序调用 onDestroy() 时,我会终止与应用程序的任何关系进程。该应用程序现在工作正常。那是我的代码。在您的 FragmentActivity 类中

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "--- ON DESTROY ---");
        killAppliactionProcess();
    }
    
    // Kill and relation process with the app
    private void killAppliactionProcess() {
        Process.killProcess(Process.myPid());
    }
    

    【讨论】:

      【解决方案3】:

      当您按下主页按钮时,您的应用基本上进入睡眠状态,它不会关闭。但是,由于当您“重新启动”时您的活动中没有暂停或恢复方法,您实际上是在打开应用程序的原始实例。这是导致错误的原因:

       Caused by: java.lang.IllegalStateException: Activity has been destroyed
      

      因为您的 Activity 不再可用。

      【讨论】:

        猜你喜欢
        • 2012-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多