通过System.exit(0)、finish()以及返回键,只能结束当前的Activity,当我们打开多个Activity并需要直接退出整个Android应用时,需要多次单击back返回键,方能退出。给用户体验不是很好。下面我们来介绍几种直接退出整个Android应用的方法。
解决方案一:
创建一个辅助类,用于保存所有的已打开的Activity,当打开一个Activity时,就将其添加到已打开的Activity集合中(通常是onCreate()方法中调用add方法),当关闭一个Activity时,需要在集合中删除该Activity(通常是onDestroy()方法中调用delete方法)。关键代码如下:
public class ActivityMgr extends Application {
private static ActivityMgr activityMgr = null;
public List<Activity> activities = new LinkedList<Activity>();
public synchronized static ActivityMgr getInstance() {
if (null == activityMgr) {
activityMgr = new ActivityMgr();
}
return activityMgr;
}
public void addActivity(Activity activity) {
if (activity != null) {
activities.add(activity);
}
}
public void exit() {
for (Activity activity : activities) {
System.out.println("Activity="+activity);
if (activity != null) {
activity.finish();
}
}
System.exit(0);
}
public void delete(Activity activity){
if(activities.contains(activity)){
activities.remove(activity);
System.out.println("Delete!");
}
}
public void onLowMemory() {
super.onLowMemory();
System.gc();
}
}
在Activity的onCreate()方法中将Activity本身添加到集合中的语句如下:
ActivityMgr.getInstance().addActivity(this);
在Activity的onDestroy()方法中,将Activity从集合中删除的语句如下:
protected void onDestroy() {
ActivityMgr.getInstance().delete(this);
super.onDestroy();
}
解决方案二:
通过发送广播的方式,通知所有的Activity进行关闭,具体做法创建一个自定义的MyActivity让其继承于Activity,在该Activity中定义一个内部广播接收器类,然后在onResume()方法中进行动态注册广播接收器。最后让其他的Activity继承于MyActivity而不是系统的Activity,这样所有的Activity类都继承了MyActivity中的onResume()方法,也就注册了广播接收器,当需要退出应用程序时,只需要发送一个广播即可,这时所有的Activity的内部广播接收器都可以接收到该广播,然后执行finish()方法,结束Activity本身。
public class MyActivity extends Activity {
ExitBroadcastReceiver exitReceiver;
private class ExitBroadcastReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
finish();//结束当前的Activity
unregisterReceiver(exitReceiver);//取消注册
}
}
protected void onResume() {
exitReceiver=new ExitBroadcastReceiver();//创建广播接收器
IntentFilter filter=new IntentFilter("iet.jxufe.cn.android.exit");//过滤条件
registerReceiver(exitReceiver, filter);//注册广播接收器
super.onResume();
}
}
需要退出时,只需要发送广播即可。代码如下:
Intent intent=new Intent();
intent.setAction("iet.jxufe.cn.android.exit");//设置接收广播的条件
sendBroadcast(intent);//发送广播
解决方案三:
通过Activity的启动模式来实现该功能,Activity的启动模式主要有以下几种:
1、standard模式;也就是默认模式,每次激活Activity时都会创建一个新的Activity实例,并放入任务栈中。
2、singleTop模式;如果在任务栈中的栈顶存在该Activity实例,下次激活该Activity实例时就不会创建新的 Activity的实例,直接重用它(在重用的这个过程中会调用实例的OnNewIntent()这个方法),否则就创建新的Activity实例。
3、singleTask模式;如果在栈中已经有该Activity的实例,以后就不会创建新的实例了,而会重用该实例(在重用的这个过程中会调用实例的OnNewIntent()这个方法)。重用时,如果该Activity实例不是在栈顶,它会让该实例回到栈顶,而它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。
4、singleInstance模式;在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。
在这里我们可以把主activity设置为singleTask模式,当我们想退出整个应用时,就可以通过intent打开该activity,然后系统会把它之上的activity移出activity栈,然后我们再在该activity的onNewIntent方法进行finish,就可以达到退出该应用程序的目的。
该方案有一定的局限性,仅适应于有一个固定的Activity作为栈底的情况,如果栈底元素不是固定的,则有可能达不到该效果。例如若此时栈中并不存在该实例对象,则会创建一个新的对象,也就达不到关闭其他Activity的目的。
Activity的启动模式可以在清单文件中进行配置,例如:
<activity
android:name="MainActivity"
android:label="@string/title_activity_main"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
在MainActivity中重写onNewIntent()方法,执行finish()方法,代码如下:
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
this.finish();
}
在需要退出整个应用时,创建一个Intent,跳转到MainActivity即可,此时由于MainActivity处于栈底,它上面的所有的Activity都会销毁,并会调用MainActivity的onNewIntent()方法。
最后介绍一种,Android彻底关闭当前应用(2.2版本不再有效)
以下方法用于关闭当前应用(此方法一般不建议使用,因为采用杀死进程的方法会导致activity所在进程被杀死,使得activity处于界面可见,但是无法响应事件,不可操作状态,也无法将activity正常结束的情况):
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
manager.restartPackage(getPackageName());
需要权限:
"android.permission.RESTART_PACKAGES"
函数说明:
void android.app.ActivityManager.restartPackage(String packageName)
public void restartPackage (String packageName)
Since: API Level 3
Have the system perform a force stop of everything associated with the given application package. All processes that share its uid will be killed, all services it has running stopped, all activities removed, etc. In addition, a ACTION_PACKAGE_RESTARTED broadcast will be sent, so that any of its registered alarms can be stopped, notifications removed, etc.
You must hold the permission RESTART_PACKAGES to be able to call this method.
Parameters
packageName The name of the package to be stopped.
与当前应用相关的应用、进程、服务等也会被关闭。
会发送 ACTION_PACKAGE_RESTARTED广播。
不要被函数名误导。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。