1. 程式人生 > >Android 監聽主程序被殺

Android 監聽主程序被殺

當按多工鍵時,然後清除所有程式或者殺死單個程式時,如果要監聽這個動作的話,可以在一個service裡監聽。

效果如下:

可以看到,在多工視窗中,左滑結束程序和清除所有程序後,都會自己再開啟應用,程式碼如下:

public class KeepLifeService extends Service {

    private static final String TAG="KeepLifeService";

    private String mPackName;
    private ActivityManager mActivityManager;

    @Override
    public void onCreate() {
        super.onCreate();
        mActivityManager =(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);

        String process=getProcessName();
        mPackName =getPackageName();
        
        boolean isRun=isRunningProcess(mActivityManager,mPackName);
        Log.i(TAG, String.format("onCreate: %s %s pid=%d uid=%d isRun=%s", mPackName,process, Process.myPid(), Process.myUid(),isRun));

        if(!isRun){
            Intent intent = getPackageManager().getLaunchIntentForPackage(mPackName);
            if(intent!=null){
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
            }
        }

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     * 獲取當前程序名稱
     *
     * @return
     */
    public static String getProcessName() {
        try {
            File file = new File("/proc/" + android.os.Process.myPid() + "/" + "cmdline");
            BufferedReader mBufferedReader = new BufferedReader(new FileReader(file));
            String processName = mBufferedReader.readLine().trim();
            mBufferedReader.close();
            return processName;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 程序是否存活
     * @return
     */
    public static boolean isRunningProcess(ActivityManager manager,String processName) {
        if(manager==null)
            return false;
        List<ActivityManager.RunningAppProcessInfo> runnings = manager.getRunningAppProcesses();
        if (runnings != null) {
            for (ActivityManager.RunningAppProcessInfo info : runnings) {
                if(TextUtils.equals(info.processName,processName)){
                    return true;
                }
            }
        }
        return false;
    }

}

AndroidManifest.xml 檔案中

<service android:name=".KeepLifeService"
            android:process=":keepLife"
            />

啟動service

 startService(new Intent(this,KeepLifeService.class));

在主程序中啟動service ,然後殺死主程序,這時service會自動重新啟動,onCreate 會重走,pid會不一樣,所以要監聽主程序被殺,只需要在service 中的oncreate 判斷主程序是否存活,不存活則為被殺,這時你可以重新啟動應用或者別的。(這裡為了演示,選擇了重新啟動應用,也算是保活手段,不過這種行為不好,別當流氓軟體)

關鍵點:

其中啟動service只能用startService ,不能用bindService,

mainifest 中service 要放單獨程序,或者子程序。

如果想要保活的話?

這個只適用於 在多工 頁殺死程序,如果用 

am force-stop packageName

殺程序的話,是不會重啟service 的。

然後是應用自己崩潰,異常,這個可以用

Thread.setDefaultUncaughtExceptionHandler

監聽,然後重啟應用,但是如果是 so 包,也就是c 層崩潰,是監聽不到異常的,這時可以用上面那個service 開執行緒,每30s 檢查一次主程序是否存活,然後再啟動之類。

本次測試Android 版本: 5.1~7.1.1,其它的自測,有效果的話可以評論留言。