Android:启动Activity后服务无法停止、禁用返回键及调用finishAffinity问题
问题解答
1. 解决Service调用stopSelf()无法终止的问题
你遇到的stopSelf()没效果,大概率是因为AsyncTask还在后台运行,导致Service所在的进程没有被系统回收——毕竟AsyncTask会开启子线程,只要这个子线程还在执行,进程就不会被销毁。
解决思路 & 代码示例
首先在Service中保存AsyncTask的引用,确保能在启动Activity前取消它(如果还在运行),再调用stopSelf():
// 在Service类中声明AsyncTask引用 private MyAsyncTask mAsyncTask; // 自定义AsyncTask子类 private class MyAsyncTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { // 你的后台任务逻辑 return null; } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); // 任务完成后自动停止Service stopSelf(); } }
然后修改启动Activity的代码:
Intent dialogIntent = new Intent(UserLoginValidationService.this, SplashScreen.class); dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); dialogIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 先取消未完成的AsyncTask if (mAsyncTask != null && mAsyncTask.getStatus() != AsyncTask.Status.FINISHED) { mAsyncTask.cancel(true); } stopSelf(); startActivity(dialogIntent);
另外要注意:如果你的Service是通过bindService()绑定的,仅调用stopSelf()不够,还需要解除所有绑定才能让Service销毁。从你的描述看应该是startService()启动的,上面的方法就能解决问题。
2. 让Activity B返回键失效,以及实现类似finishAffinity()的效果
(1)禁用Activity B的返回键
有两种简单的实现方式:
- 重写
onBackPressed():在Activity B的代码里空实现这个方法,直接拦截返回键:
@Override public void onBackPressed() { // 空实现,按下返回键无任何反应 }
- 拦截返回键事件:通过
onKeyDown()方法拦截:
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { return true; // 拦截返回键操作 } return super.onKeyDown(keyCode, event); }
(2)在Service中实现类似finishAffinity()的效果
finishAffinity()是Activity独有的方法,Service无法直接调用,你可以通过以下两种方式间接实现:
- 方式一:增强Intent的Flags
给Intent加上FLAG_ACTIVITY_CLEAR_TASK,它会清除整个任务栈,只保留Activity B,之前的Activity A会被直接销毁:
Intent dialogIntent = new Intent(UserLoginValidationService.this, SplashScreen.class); dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); dialogIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); dialogIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); // 新增该Flag startActivity(dialogIntent);
这样进入Activity B后,按下返回键会直接退出应用,而非回到Activity A。
- 方式二:让Activity B自行调用
finishAffinity()
在Activity B的onCreate()方法中调用该方法,关闭当前任务栈中所有的Activity:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); finishAffinity(); // 关闭所有之前的Activity }
内容的提问来源于stack exchange,提问作者Anand
相关产品推荐
相关产品推荐

