Android两行代码真正杀死你的App

本文介绍了两种在Android应用中彻底退出应用的方法。一种是通过ActivityCollector管理所有Activity并调用finishAll()方法关闭它们;另一种是直接使用finishAffinity()方法。之后调用System.exit(0)或Process.killProcess()来确保应用完全终止。

Android上杀掉进程的方式有两种,分别是System.exit(0)和Process.killProcess(Process.myPid()),这两种方法比较暴力,App进程会被直接杀掉,但是由于Android的安全机制,你会发现,在调用上述两种方法后,App会被自动重启,并未达到我们想要的杀死状态!那我们该怎样实现真正的杀死App呢?

我认为需要两个步骤

一、关闭打开的所有Activity

二、调用System.exit(0)或Process.killProcess(Process.myPid())


先介绍两种关闭所有Activity的方法:


1、这第一种方法是郭神在《第一行代码》中讲到的,我在这引用一下。

首先我们需要用一个专门的集合类对所有的活动进行管理,新建一个ActivityCollector类作为活动管理器,代码如下所示:

private static List<Activity> activities = new ArrayList<>();

    public static void addActivity(Activity activity) {
        activities.add(activity);
    }
    public static void removeActivity(Activity activity) {
        activities.remove(activity);
    }
    public static void finishAll() {
        for (Activity activity : activities) {
            if (!activity.isFinishing()) {
                activity.finish();
            }
        }
        activities.clear();
    }

在活动管理器中,我们通过一个List来暂存活动,然后提供了addActivity()方法用于向List中添加一个活动,提供了removeActivity()方法用于从List中移除活动,最后提供了finishAll()方法用于将List中存储的活动全部销毁掉。

接下来我们创建一个BaseActivity(这是一个继承至AppCompatActivity的普通java类,不需要在AndroidManifest中注册),之后我们所创建的所有Activity均需要继承至这个BaseActivity,代码如下所示:

public class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("BaseActivity", getClass().getSimpleName());
        ActivityCollector.addActivity(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }

}

BaseActivityonCreate()方法中调用了ActivityCollectoraddActivity()方法,表明将当前正在创建的活动添加到活动管理器里。然后在BaseActivity中重写onDestroy()方法,并调用了ActivityCollectorremoveActivity()方法,表明将一个马上要销毁的活动从活动管理器里移除。

从此以后,不管你想在什么地方退出程序,只需要调用ActivityCollector.finishAll()方法就可以了。

2、这第二种方法相当简单给力!只需要一行代码!

在Activity中:

finishAffinity();
如果在Fragment中:

getActivity().finishAffinity();

OK!现在我们已经将所有Activity关闭了,接下来只需要调用System.exit(0)或Process.killProcess(Process.myPid())中的一种,就可以实现在任意地方,随时随地真正的杀死App了!






@echo off chcp 65001 >nul set "SCRIPT_DIR=%~dp0" rem 获取当前时间,格式为:202502211025 for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a" set "LOG_FILE_APP1=%SCRIPT_DIR%国内APPlog_%dt:~0,8%%dt:~8,4%.log" set "LOG_FILE_APP2=%SCRIPT_DIR%海外APPlog_%dt:~0,8%%dt:~8,4%.log" set "LOG_FILE_ALL=%SCRIPT_DIR%手机全量_%dt:~0,8%%dt:~8,4%.log" rem 获取 com.dpvr.android.app 的进程 ID adb shell pidof com.dpvr.android.app > pid.tmp set /p PID=<pid.tmp del pid.tmp echo com.dpvr.android.app 进程 ID: %PID% if "%PID%"=="" ( echo 未获取到 com.dpvr.android.app 的进程 ID,不进行该应用的日志抓取 ) rem 获取 com.dpvr.android.app.Occident 的进程 ID adb shell pidof com.dpvr.android.app.Occident > pid_occident.tmp set /p PID_OCCIDENT=<pid_occident.tmp del pid_occident.tmp echo com.dpvr.android.app.Occident 进程 ID: %PID_OCCIDENT% if "%PID_OCCIDENT%"=="" ( echo 未获取到 com.dpvr.android.app.Occident 的进程 ID,不进行该应用的日志抓取 ) if not "%PID%"=="" ( if not "%PID_OCCIDENT%"=="" ( rem 两个应用都有进程 ID,分别在后台启动日志抓取任务 echo 开始抓取APP日志,10秒后关闭窗口结束抓取 start /B "" adb logcat -v time --pid=%PID% > "%LOG_FILE_APP1%" start /B "" adb logcat -v time --pid=%PID_OCCIDENT% > "%LOG_FILE_APP2%" ) else ( rem 只有 com.dpvr.android.app 有进程 ID,只抓取它的日志 echo 开始抓取APP日志,10秒后关闭窗口结束抓取 adb logcat -v time --pid=%PID% > "%LOG_FILE_APP1%" ) ) else ( if not "%PID_OCCIDENT%"=="" ( rem 只有 com.dpvr.android.app.Occident 有进程 ID,只抓取它的日志 echo 开始抓取APP日志,10秒后关闭窗口结束抓取 adb logcat -v time --pid=%PID_OCCIDENT% > "%LOG_FILE_APP2%" ) else ( rem 两个应用都没有进程 ID,抓取全量 logcat 日志 echo 开始抓取全量LOG,10秒后关闭窗口结束抓取 adb logcat -v time > "%LOG_FILE_ALL%" ) ) timeout /t 30 /nobreak >nul
06-04
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值