用户取消SENDTO选择器后getSupportFragmentManager()崩溃应用程序(但如果打开电子邮件应用程序则不会崩溃)

时间:2013-08-15 01:30:43

标签: android fragment

我使用一种相当简单的方法从链接到视图的OnClickListener发送电子邮件:

TextView emailAddr = (TextView) findViewById(R.id.tvEmailAddr);
emailAddr.setOnClickListener(emailClick);

在同一项活动中,我有OnClickListener

final OnClickListener emailClick = new OnClickListener() {
    @Override
    public void onClick(View view) {
            Intent intent = new Intent(Intent.ACTION_SENDTO, 
                Uri.parse("dearjohn@acme.com"));
            intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.contactsEMailSubject));
            startActivity(intent);
    }
};

注意: 我也使用匿名侦听器进行此设置,结果完全相同。

如果没有默认的电子邮件应用程序,用户将看到一个选择器窗口。如果他们继续发送电子邮件,一切都很好,如果没有,他们取消选择器对话框我的应用程序崩溃。

我将问题跟踪到尝试在refreshData()方法(从onResume()调用)中显示进度对话框。

我的progressDialog代码如下所示:(也许我在这里遗漏了一些东西,这意味着我在某些情况下无法重复使用它?)

public class HttpProgressDlg extends DialogFragment 
    implements OnCancelListener, OnDismissListener {

    interface HttpProgressDlgCancelListener {
        void onCancelHttpProgressDlg();
    }

    public HttpProgressDlg() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
            Bundle savedinstanceState){
        View view = inflater.inflate(R.layout.http_progress, container);
        getDialog().setTitle(getString(R.string.dlgProgressTitle));
        getDialog().setOnCancelListener(this);
        return view;
    }

    @Override
    public void onCancel(DialogInterface dialog) {
        HttpProgressDlgCancelListener activity = (HttpProgressDlgCancelListener) getActivity();
        activity.onCancelHttpProgressDlg();  // tell activity to cancel http request
        this.dismiss();  // "close" the dialog
    }

和试图使用它的代码:

protected void showProgressDialog() {
    FragmentManager fragmentMgr = getSupportFragmentManager();
    httpProgressDlg = new HttpProgressDlg();
    httpProgressDlg.show(fragmentMgr, "http_progress");
}

我认为问题是getSupportFragmentManager()返回null。 (是的,我可以检查一下,我有 - 稍后再详细说明)

当用户取消选择器对话框时会发生什么,Android当然希望恢复活动。我的踪迹带我进入 1. onSaveInstanceState(很奇怪)完成确定。 2. onResume - 设置视图的文本,隐藏或显示另一个视图,然后调用调用showProgressDialog()的refreshData。

与此每次调用代码时不同,它返回null,除非我真的拖出跟踪/调试过程,在这种情况下它可以正常工作。似乎有一些进程使其返回null。

LogCat在调用onSavewInstanceState后显示一些有关非法状态的奇怪消息:

08-15 10:49:55.187: D/AndroidRuntime(16016): Shutting down VM
08-15 10:49:55.187: W/dalvikvm(16016): threadid=1: thread exiting with uncaught exception (group=0x41b682a0)
08-15 10:49:55.227: E/AndroidRuntime(16016): FATAL EXCEPTION: main
08-15 10:49:55.227: E/AndroidRuntime(16016): java.lang.RuntimeException: Unable to resume activity {com.viterra.glencoregrain/com.viterra.glencoregrain.MainActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2616)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2644)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.os.Looper.loop(Looper.java:137)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.app.ActivityThread.main(ActivityThread.java:4898)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at java.lang.reflect.Method.invokeNative(Native Method)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at java.lang.reflect.Method.invoke(Method.java:511)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at dalvik.system.NativeStart.main(Native Method)
08-15 10:49:55.227: E/AndroidRuntime(16016): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.support.v4.app.DialogFragment.show(DialogFragment.java:127)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at com.viterra.glencoregrain.GlencoreBaseActivity.showProgressDialog(GlencoreBaseActivity.java:274)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at com.viterra.glencoregrain.MainActivity.refreshData(MainActivity.java:113)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at com.viterra.glencoregrain.GlencoreBaseActivity.onResume(GlencoreBaseActivity.java:103)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at com.viterra.glencoregrain.MainActivity.onResume(MainActivity.java:41)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1188)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.app.Activity.performResume(Activity.java:5280)
08-15 10:49:55.227: E/AndroidRuntime(16016):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2606)
08-15 10:49:55.227: E/AndroidRuntime(16016):    ... 10 more
08-15 10:50:09.132: I/Process(16016): Sending signal. PID: 16016 SIG: 9

我现在已经设置了一个循环来确保它不会结束,直到我返回一个非null值,就像这样(仅用于测试理解)

FragmentManager fragmentMgr = null;
while (fragmentMgr == null) { 
    fragmentMgr = getSupportFragmentManager();
}   
httpProgressDlg = new HttpProgressDlg();
httpProgressDlg.show(fragmentMgr, "http_progress");

然后代码进入httpProgressDlg.show(...)部分崩溃的地方...... 我根本没有得到这个。转移到其他活动并返回(也使用“startActivity(intent ...”代码不会导致此崩溃,仅当我取消选择器时。

1 个答案:

答案 0 :(得分:0)

您不应在onResume中手动显示对话框片段,因为Android会自动恢复它们。