Android检测Activity或者Service是否运行的方法
作者:码不停蹄子 发布时间:2021-09-03 00:52:00
标签:Activity,Service,运行,Android
需求:假设我们的APP有3个页面AActivity,BActivity,CActivity,我们的APP需要一直运行在前台(特殊设备),要求实现一个监控服务,来监视APP是否运行,如果有3个页面都不运行了就说明这个APP已经挂掉了,否则说明APP在运行状态,不做处理,挂掉之后,我们需要重新启动App来让它继续处理运行状态,对外暴露一个来停止监控服务的广播,这样我们想停止监控服务时,发送一个广播即可。
思路:实现一个双进程的监控服务,服务中写一个定时器 Timer 来重复进行检测是否正在运行,如果否就直接重新启动APP。
1.定义一个监控服务
package com.anloq.nfcservice;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import com.anloq.MyApplication;
import com.anloq.activity.AdActivity;
import com.anloq.utils.DetectionASUtils;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by xpf on 2017/6/3 :)
* 检测APP页面是否一直运行,不运行就直接启动
*/
public class MonitoringService extends Service {
private final static String TAG = "MonitoringService";
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if ("kill_self".equals(intent.getAction())) {
Log.e(TAG, "onReceive:杀死自己的进程!");
killMyselfPid(); // 杀死自己的进程
}
}
};
private Timer timer = new Timer();
private TimerTask task = new TimerTask() {
@Override
public void run() {
checkIsAlive();
}
};
/**
* 检测应用是否活着
*/
private void checkIsAlive() {
String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
Locale.CHINA).format(new Date());
Log.e(TAG, "CustodyService Run: " + format);
boolean AIsRunning = CheckUtil.isClsRunning(
MonitoringService.this, "com.xpf.monitor", "com.xpf.monitor.activity.AActivity");
boolean BIsRunning = CheckUtil.isClsRunning(
MonitoringService.this, "com.xpf.monitor", "com.xpf.monitor.activity.BActivity");
boolean b = (AIsRunning || BIsRunning);
boolean CIsRunning = CheckUtil.isClsRunning(
MonitoringService.this, "com.xpf.monitor", "com.xpf.monitor.activity.CActivity");
Log.e(TAG, "AIsRunning || BIsRunning is running:" + b + ",CIsRunning:" + CIsRunning);
if (!CIsRunning) {
if (!b) { //如果界面挂掉直接启动AActivity
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(MonitoringService.this, AActivity.class);
startActivity(intent);
}
}
}
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate: 启动监控服务! ");
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("kill_self");
registerReceiver(broadcastReceiver, intentFilter);
timer.schedule(task, 0, 10000);// 设置检测的时间周期(毫秒数)
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
/**
* 杀死自身的进程
*/
private void killMyselfPid() {
int pid = android.os.Process.myPid();
String command = "kill -9 " + pid;
Log.e(TAG, "killMyselfPid: " + command);
stopService(new Intent(MonitoringService.this, MonitoringService.class));
try {
Runtime.getRuntime().exec(command);
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
if (task != null) {
task.cancel();
}
if (timer != null) {
timer.cancel();
}
}
}
2.注册双进程Service
<service
android:name="com.xpf.monitor.MonitoringService"
android:enabled="true"
android:label="MonitoringService"
android:process=":gray">
<intent-filter>
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
</intent-filter>
</service>
3.检测是否活着的工具类CheckUtil
public class CheckUtil {
//检测service是否在运行
public static boolean isServiceWorked(Context context, String serviceName) {
ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ArrayList<ActivityManager.RunningServiceInfo> runningService = (ArrayList<ActivityManager.RunningServiceInfo>) myManager.getRunningServices(Integer.MAX_VALUE);
for (int i = 0; i < runningService.size(); i++) {
if (runningService.get(i).service.getClassName().toString().equals(serviceName)) {
return true;
}
}
return false;
}
//检测activity是否存在再栈顶
public static boolean isForeground(Context context, String PackageName) {
ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> task = myManager.getRunningTasks(1);
ComponentName componentInfo = task.get(0).topActivity;
if (componentInfo.getPackageName().equals(PackageName))
return true;
return false;
}
/**
* 判断某个app进程是否在运行
*
* @param context
* @param appInfo
* @return
*/
public static boolean isRunningProcess(Context context, String appInfo) {
ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppPs = myManager.getRunningAppProcesses();
if (runningAppPs != null && runningAppPs.size() > 0) {
if (runningAppPs.contains(appInfo)) {
return true;
}
}
return false;
}
/**
* 判断一个Activity是否正在运行
*
* @param pkg pkg为应用包名
* @param cls cls为类名eg
* @param context
* @return
*/
public static boolean isClsRunning(Context context, String pkg, String cls) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
ActivityManager.RunningTaskInfo task = tasks.get(0);
if (task != null) {
return TextUtils.equals(task.topActivity.getPackageName(), pkg) &&
TextUtils.equals(task.topActivity.getClassName(), cls);
}
return false;
}
}
4.MainActivity中启动监控服务
Intent intent = new Intent(MainActivity.this, MonitoringService.class);
intent.setAction("android.intent.action.RESPOND_VIA_MESSAGE");
startService(intent);
5.停止监控服务
发送一个杀死进程广播即可,action值如下
Intent intent = new Intent();
intent.setAction("kill_self");
sendOrderedBroadcast(intent, null);
来源:https://blog.csdn.net/xinpengfei521/article/details/78812597


猜你喜欢
- Java执行hadoop的基本操作实例代码向HDFS上传本地文件public static void uploadInputFile(Str
- 五子棋游戏(Java),供大家参考,具体内容如下思路:1.首先创建一个棋盘,建立一个二维数组,此文中为一个15*15的二维数组,2.初始化棋
- 本地仓库是指存在于我们本机的仓库,在我们加入依赖时候,首先会跑到我们的本地仓库去找,如果找不到则会跑到远程仓库中去找。对于依赖的包大家可以从
- 本文是利用C# 实现FTP客户端的小例子,主要实现上传,下载,删除等功能,以供学习分享使用。思路:通过读取FTP站点的目录信息,列出对应的文
- 在action中存放数据,代码如下:@Controller // 加入到IOC容器//@RequestMapping(value="
- app的启动方式: 1.)冷启动 当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启
- 写在前面:使用springboot作为web框架,方便开发许多,做分布式开发,dubbo又不可少,那么怎么整合在一起呢,跟我学一遍,至少会用
- DataGridView是Visual Studio中一个最重要的数据控件。它可以应用在大多数场合,功能强大,使用灵活。本文要重点介绍一下,
- 最近IDEA打可执行Jar包搞了三天,一直失败,好好学习一下Maven-assembly,在此记录一下1. 需求项目打包,满足以下要求:1.
- JAVA常用关键字及其用法简要说明Abstract: 抽象的 一个Java语言中的关键字,用在类的声明中来指明一个类是不能被实例化的,但是可
- C# 泛型(Generic)定义:泛型允许我们延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。也就是说,泛型是可
- 前言有时候我们开发时会发现有些方法调用非常多,但它的默认的调用方法却要传很多参数进去而且还得记得调用具体的写法,比如Toast,不止要调用m
- SpringBoot底层的一个功能 : @ConfigurationProperties@ConfigurationProperties 配
- Bean:在Spring技术中是基于组件的最基本了是最常用的单元其实实例保存在Spring的容器当中Bean通常被定义在配置文件当中,Bea
- 目的:在使用mybatis框架中mapper文件有自动生成,但有时需要自己添加sql语句进行开发,当遇到需要使用 if进行条件判断的时候该怎
- 最近被.net winform中的控件布局搞困惑了,由于控件都是使用Dock方式的,操作起来也是比较方便,如果最大化,窗口大小调整等,都可以
- Android 6本文根据我个人的开发经验,总结了从 Android 6 - Android 13 重要的行为变更。当然,这不是 Andro
- (一).前言: 这两天QQ进行了重大更新(6.X)尤其在UI风格上面由之前的蓝色换成了白色居多了,侧滑效果也发生了一些变化,那我们今天来模仿
- 默认路径在Spring Boot 2.7.2版本中,查看默认静态资源路径,在WebProperties.class中如下private st
- 本文实例为大家分享了shader实现基于世界坐标的贴图置换效果。效果如下:设置面板如下:可在面板上设置切换方向,与切换对象,及其切换速度。s