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 ...”代码不会导致此崩溃,仅当我取消选择器时。