Android Studio菜单点击后启动全部Activity并崩溃问题求助
问题:点击任意菜单项会依次启动所有Activity并崩溃
问题现象
- 点击菜单中任意选项,会依次启动所有对应的Activity,随后应用崩溃
- 已通过
menu.removeItem()移除的菜单项也会触发该问题 - 仅弹出对话框的About项无此异常
问题代码
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); menu.removeItem(R.id.HomePage); if (sp.getLong("User_Id", -1) != -1) { menu.removeItem(R.id.Login); menu.removeItem(R.id.SignUp); } else { menu.removeItem(R.id.LogOut); } if (sp.contains("User_Id")){ if (!database.userDao().GetUserById(sp.getLong("User_Id", -1)).getUserEmail().equals(R.string.admin_email)) menu.removeItem(R.id.UserList); } else menu.removeItem(R.id.UserList); return true; } @SuppressLint("NonConstantResourceId") @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.SignUp: { startActivity(new Intent(MainActivity.this, RegisterActivity.class)); } case R.id.Login: { startActivity(new Intent(MainActivity.this, LoginActivity.class)); } case R.id.UserList: { startActivity(new Intent(MainActivity.this, UserActivity.class)); } case R.id.LogOut:{ builder.setMessage(R.string.logout_dialog_message).setTitle(R.string.logout_dialog_title).setCancelable(true).setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { editor.clear(); editor.commit(); finish(); overridePendingTransition(0, 0); startActivity(getIntent()); overridePendingTransition(0, 0); } }).setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); AlertDialog alert = builder.create(); alert.show(); } case R.id.About: { Dialog dialog = new Dialog(MainActivity.this); dialog.setContentView(R.layout.custom_about_dialog); dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); dialog.setCancelable(true); dialog.getWindow().getAttributes().windowAnimations = R.style.animation; ImageView image = dialog.findViewById(R.id.IVLogo); TextView text = dialog.findViewById(R.id.TVText); image.setBackground(getDrawable(R.drawable.logo)); text.setText("About us: We are regel2, the new best second hand app. In this app, you are able to buy and sell any product that you want, for any price that you want, all inside 1 app."); dialog.show(); } } return super.onOptionsItemSelected(item); }
问题原因
核心问题是onOptionsItemSelected方法中的switch语句所有case分支都没有添加break关键字,导致代码执行会贯穿所有后续的case。比如点击SignUp项时,代码会先执行启动RegisterActivity的逻辑,然后不中断,继续执行Login分支启动LoginActivity,接着是UserList、LogOut,直到最后About分支的代码,最终依次启动多个Activity,引发崩溃。
另外,方法末尾调用return super.onOptionsItemSelected(item)会让系统继续处理该菜单事件,可能导致额外的问题,正确的做法是处理完对应case后返回true表示事件已被处理。
修复后的代码
@SuppressLint("NonConstantResourceId") @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.SignUp: { startActivity(new Intent(MainActivity.this, RegisterActivity.class)); return true; // 表示事件已处理,无需系统再处理 } case R.id.Login: { startActivity(new Intent(MainActivity.this, LoginActivity.class)); return true; } case R.id.UserList: { startActivity(new Intent(MainActivity.this, UserActivity.class)); return true; } case R.id.LogOut:{ builder.setMessage(R.string.logout_dialog_message).setTitle(R.string.logout_dialog_title).setCancelable(true).setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { editor.clear(); editor.commit(); finish(); overridePendingTransition(0, 0); startActivity(getIntent()); overridePendingTransition(0, 0); } }).setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); AlertDialog alert = builder.create(); alert.show(); return true; } case R.id.About: { Dialog dialog = new Dialog(MainActivity.this); dialog.setContentView(R.layout.custom_about_dialog); dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); dialog.setCancelable(true); dialog.getWindow().getAttributes().windowAnimations = R.style.animation; ImageView image = dialog.findViewById(R.id.IVLogo); TextView text = dialog.findViewById(R.id.TVText); image.setBackground(getDrawable(R.drawable.logo)); text.setText("About us: We are regel2, the new best second hand app. In this app, you are able to buy and sell any product that you want, for any price that you want, all inside 1 app."); dialog.show(); return true; } default: return super.onOptionsItemSelected(item); // 未匹配到的项交给系统处理 } }
额外建议
- 对于
onCreateOptionsMenu中移除菜单项的逻辑,可以优化为直接根据登录状态加载不同的菜单资源,避免动态移除的复杂性 - 注意
database.userDao().GetUserById(...)的调用如果是在主线程,可能会引发ANR,建议放在异步线程中执行
内容的提问来源于stack exchange,提问作者ShaharKarisi
相关产品推荐
相关产品推荐

