0
点赞
收藏
分享

微信扫一扫

Android退出应用程序方法总结

查拉图斯特拉你和他 2022-04-01 阅读 138
android

1.finish方法

finish();

该方法只是结束当前Activity,系统将最上面的Activity移出了栈,并没有清理占用的资源。如果栈内有很多Activity 的话,使用该方法显得有点捉襟见肘了,没办法一次移出全部Activity,并且没有立即释放内存,活动的资源也没有被清理。

2. 进程式

  • KillProcess(): 可以杀死当前应用活动的进程,这一操作将会把所有该进程内的资源(包括线程全部清理掉)。当然,由于ActivityManager时刻监听着进程,一旦发现进程被非正常Kill,它将会试图去重启这个进程。                                                                                                                        
    android.os.Process.killProcess(android.os.Process.myPid());
  • System.exit(): Java中结束进程的方法,调用它将关闭当前的JVM虚拟机。
  • System.exit(0);//正常退出
    System.exit(1);//非正常退出

 3. 根据Activity的生命周期

Android的窗口类提供了历史栈,可以通过stack的原理来巧妙的实现。在A窗口打开B窗口的时候,在Intent中直接加入标识Intent.FLAG_ACTIVITY_CLEAR_TOP,这样开启B时,会清除该进程空间的所有Activity。

1)在A窗口中调用该方法跳转到B窗口:

Intent intent = new Intent();
intent.setClass(AActivity.this,BActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

2)在B窗口退出时直接使用 finish 方法即可全部退出:

finish();

4. 任务管理器

系统将终止一切和这个程序包关联的,所有共享同一 uid 的 process全部杀掉,还会停止相关的服务,并且会发送一个广播。

<uses-permission android:name="android.permission.RESTART_PACKAGES"/>
ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);
am.restartPackage(getPackageName());

但是在 Android 2.2(API 8)之后,restartPackage方法已经过时,不可以将应用程序结束,需要使用ActivityManager类的killBackgroundProcesses方法。

<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>  
ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);
am.killBackgroundProcesses(getPackageName());
System.exit(0);

 5. 任务栈式

利用一个单例模式的Activity栈来管理所有Activity

1)自定义 Application类,储存每一个Activity,并实现关闭所有Activity的操作

public class MyApplication extends Application {    
private List<Activity> activityList = new LinkedList<Activity>();
private static MyApplication instance;


/**
*单例模式 1:
*/

private MyApplication() {
}

public static MyApplication getInstance() {
if(null == instance) {
instance = new MyApplication();
}
return instance;
}

@Override
public void onCreate() {
super.onCreate();
}


/**
*单例模式 2:
*/

// public static MyApplication getInstance() {
// return instance;
// }

// @Override
// public void onCreate() {
// super.onCreate();
// instance = this;
// }


//添加Activity到容器中
public void addActivity(Activity activity) {
activityList.add(activity);
}

//遍历所有Activity并finish
public void exit() {
for(Activity activity:activityList) {
activity.finish();
}
activityList.clear();
}
}

 2)在父类BaseActivity中添加继承子类Activity到栈中

public class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 添加Activity到堆栈
        MyApplication.getInstance().addActivity(this);
    }
    ...
}

3)在需要结束所有Activity的时候调用 exit 方法

MyApplication.getInstance().exit();

6. 容器式

类似 5(任务栈式),自定义一个Actiivty栈,通过单例模式的Activity栈来管理所有Activity

1)建立一个全局容器,把所有的Activity存储起来

public class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 添加Activity到堆栈
        AtyContainer.getInstance().addActivity(this);
    }
    ...
}

2)创建Activity管理类

public class AtyContainer {

    public AtyContainer() {
    }

    private static AtyContainer instance = new AtyContainer();
    private static List<Activity> activityStack = new ArrayList<Activity>();
    public static AtyContainer getInstance() {
        return instance;
    }

    /**
     * 添加Activity到堆栈
     */
    public void addActivity(Activity activity) {
        if (activityStack == null) {
            activityStack = new ArrayList<Activity>();
        }
        activityStack.add(activity);
    }

    /**
     * 移除指定的Activity
     */
    public void removeActivity(Activity activity) {
        if (activity != null) {
            activityStack.remove(activity);
            activity = null;
        }
    }
    /**
    * 结束所有Activity
    */
    public void finishAllActivity() {
        for (int i = 0, size = activityStack.size(); i < size; i++) {
            if (null != activityStack.get(i)) {
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }
}

3)在退出时循环遍历finish所有Activity

 AtyContainer.getInstance().finishAllActivity();

7. 清空堆栈 

1)设置MainActivity的加载模式为singleTask

android:launchMode="singleTask"

2)重写MainActivity中的onNewIntent方法

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    if (intent != null) {
        boolean isExit = intent.getBooleanExtra("exit", false);
        if (isExit) {
            finish();
        }
    }
}

3)需要退出时在Intent中添加退出的Tag

/**退出程序*/
protected void exit() {
    // 这里使用clear + new task的方式清空整个任务栈,只保留新打开的Main页面
    // 然后Main页面接收到退出的标志位exit=true,finish自己,这样就关闭了全部页面
    Intent intent = new Intent(this, MainActivity.class);
    intent.putExtra("exit", true);
    startActivity(intent);
}

8. 销毁任务栈

直接调用系统 API获取当前的任务栈,把里面的Activity全部销毁掉。不过该方法简单粗暴,需要 API 21(Android 5.0)以上才可以使用。

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void exitAPP() {
        ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.AppTask> appTaskList = activityManager.getAppTasks();
        for (ActivityManager.AppTask appTask : appTaskList) {
            appTask.finishAndRemoveTask();
        }
    }

9. 广播式

通过在全局中注册一个广播,当退出时发送一个广播退出

1)在BaseActivity中注册广播

public class BaseActivity extends Activity {

private static final String EXITACTION = "action.exit";
private ExitReceiver exitReceiver = new ExitReceiver();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction(EXITACTION);
registerReceiver(exitReceiver, filter);
}

@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(exitReceiver);
}

class ExitReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
finish();
}
}

}

2)发送广播退出

public class MainActivity extends BaseActivity {
private long exitTime = 0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 物理返回键,双击退出
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
if ((System.currentTimeMillis() - exitTime) > 2000) {
Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
//发送广播退出程序
Intent intent = new Intent("com.xxx.BaseActivity");
intent.putExtra(EXITACTION, 1);
sendBroadcast(intent);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
}

10. 懒人式

1)将MainActivity设置为singleTask

android:launchMode="singleTask"

2)将退出出口放置在MainActivity

private boolean mIsExit;
/**双击返回键退出*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mIsExit) {
this.finish();
} else {
Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
mIsExit = true;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mIsExit = false;
}
}, 2000);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
...

11. 退回系统桌面

Android应用开发中,有一种场景,就是我们不希望用户直接按Back键退出Activity,而是希望应用隐藏到后台的假退出,类似于按Home键的效果。(例如QQ、微信等)

方法一:

moveTaskToBack(true);//将Activity退到后台,注意不是finish()退出。

方法二:

/**退出程序**/
protected void exit() {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
System.exit(0);
}

方法三:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxx.xxx"
android:versionCode="1"
android:versionName="1.0.1">
<application>
<activity
android:name="com.xxx.xxx.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
...
</application>
</manifest>

12. 监听式

从Android 4.0(API 14)开始,Application中多了一个可以设置全局监听Activity生命周期的方法:registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback),其中传入的参数 ActivityLifecycleCallbacks能得到全局所有Activity生命周期的回调,所以我们可以从Application中全局监听所有Activity并对其进行管理

public class MyApplication extends Application {
protected static Context context;

/**
* 维护Activity 的list
*/

private static List<Activity> mActivitys = Collections.synchronizedList(new LinkedList<Activity>());

@Override
public void onCreate() {
super.onCreate();
context = this.getApplicationContext();
registerActivityListener();
}

public static Context getContext() {
return context;
}

/**
* @param activity 作用说明 :添加一个activity到管理里
*/

public void pushActivity(Activity activity) {
mActivitys.add(activity);
}

/**
* @param activity 作用说明 :删除一个activity在管理里
*/

public void popActivity(Activity activity) {
mActivitys.remove(activity);
}

/**
* get current Activity 获取当前Activity(栈中最后一个压入的)
*/

public static Activity currentActivity() {
if (mActivitys == null||mActivitys.isEmpty()) {
return null;
}
Activity activity = mActivitys.get(mActivitys.size()-1);
return activity;
}

/**
* 结束当前Activity(栈中最后一个压入的)
*/

public static void finishCurrentActivity() {
if (mActivitys == null||mActivitys.isEmpty()) {
return;
}
Activity activity = mActivitys.get(mActivitys.size()-1);
finishActivity(activity);
}

/**
* 结束指定的Activity
*/

public static void finishActivity(Activity activity) {
if (mActivitys == null||mActivitys.isEmpty()) {
return;
}
if (activity != null) {
mActivitys.remove(activity);
activity.finish();
activity = null;
}
}

/**
* 结束指定类名的Activity
*/

public static void finishActivity(Class<?> cls) {
if (mActivitys == null||mActivitys.isEmpty()) {
return;
}
for (Activity activity : mActivitys) {
if (activity.getClass().equals(cls)) {
finishActivity(activity);
}
}
}

/**
* 按照指定类名找到activity
*
* @param cls
* @return
*/

public static Activity findActivity(Class<?> cls) {
Activity targetActivity = null;
if (mActivitys != null) {
for (Activity activity : mActivitys) {
if (activity.getClass().equals(cls)) {
targetActivity = activity;
break;
}
}
}
return targetActivity;
}

/**
* @return 作用说明 :获取当前最顶部activity的实例
*/

public Activity getTopActivity() {
Activity mBaseActivity = null;
synchronized (mActivitys) {
final int size = mActivitys.size() - 1;
if (size < 0) {
return null;
}
mBaseActivity = mActivitys.get(size);
}
return mBaseActivity;

}

/**
* @return 作用说明 :获取当前最顶部的acitivity 名字
*/

public String getTopActivityName() {
Activity mBaseActivity = null;
synchronized (mActivitys) {
final int size = mActivitys.size() - 1;
if (size < 0) {
return null;
}
mBaseActivity = mActivitys.get(size);
}
return mBaseActivity.getClass().getName();
}

/**
* 结束所有Activity
*/

public static void finishAllActivity() {
if (mActivitys == null) {
return;
}
for (Activity activity : mActivitys) {
activity.finish();
}
mActivitys.clear();
}

/**
* 退出应用程序
*/

public static void appExit() {
try {
finishAllActivity();
} catch (Exception e) {
}
}

private void registerActivityListener() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
/**
* 监听到 Activity创建事件 将该 Activity 加入list
*/

pushActivity(activity);
}

@Override
public void onActivityStarted(Activity activity) {

}

@Override
public void onActivityResumed(Activity activity) {

}

@Override
public void onActivityPaused(Activity activity) {

}

@Override
public void onActivityStopped(Activity activity) {

}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

}

@Override
public void onActivityDestroyed(Activity activity) {
if (null==mActivitys||mActivitys.isEmpty()) {
return;
}
if (mActivitys.contains(activity)) {
/**
* 监听到 Activity销毁事件 将该Activity 从list中移除
*/

popActivity(activity);
}
}
});
}
}

}

13.finishAffinity结束当前栈内所有activity

调用activity对象的finishiAffinity()方法,可以关闭当前activity所属的activity栈中所有的activity。如果所有activity都保存在默认栈中,则使用该方法会直接退出程序。如多Acitivity跳转之后,想要结束某一些Activity而只留下某一个Activity时,你就可以在则可以在manifest文件中将该activity设置为单独的栈保存。

<activity
android:name="com.xxx.xxx.MainActivity"
android:taskAffinity=":finish"//指定栈别名
/>

在Activity中调用ActivityCompat.finishAffinity(this),相同栈名的都会被关闭。

ActivityCompat.finishAffinity(CoordinatorActovity.this);  //关闭你启动的当前activity栈中的所有的activity

结语

以上整理了目前Android退出应用程序常见的一些方法,每个方法各有利弊,大家可以去实践下,看看其具体效果,然后根据自己的需要,选择适合自己的方式。

参考:Android退出应用程序方法总结 - 简书

举报

相关推荐

0 条评论