0

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- 设置视图的文本,隐藏或显示另一个视图,然后调用 refreshData 调用showProgressDialog().

与其他每次调用代码不同,这次它返回 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

我现在已经设置了一个循环,以确保它在我返回一个非空值之前不会结束,就像这样(只是为了测试理解)

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

然后代码继续到httpProgressDlg.show(...)它崩溃的部分......我根本不明白。移动到其他活动并返回(也使用“startActivity(intent ...”代码不会导致此崩溃,仅当我取消选择器时。

4

1 回答 1

0

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

于 2013-08-15T03:03:04.240 回答