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
0
投稿
猜你喜欢
- 介绍使用mybatis时可以使用二级缓存提高查询速度,进而改善用户体验。使用redis做mybatis的二级缓存可是内存可控<如将单独
- 1、需要引入依赖<dependency> &l
- 本文实例讲述了Android中ListView下拉刷新的实现方法。分享给大家供大家参考,具体如下:ListView中的下拉刷新是非常常见的,
- 项目要求1.初次打开程序时右上角标题栏显示“无连接”,点击旁边的按钮选择“我的好友”,进入配对界面;2.选择好友之后,返回主界面,标题栏会显
- Swagger是一款遵循 Restful 风格的接口文档开发神器,支持基于 API 自动生成接口文档,接口文档始终与 API 保持同步,不再
- 可能经常看面经的同学都知道,面试所遇到的排序算法,快速排序占主要位置,热度只增不减啊,其次就是归并和堆排序。其实以前写过一篇排序的文章,写的
- 本文实例讲述了C#将HashTable中键列表或值列表复制到一维数组的方法。分享给大家供大家参考。具体如下:下面的示例说明如何将 Hasht
- Java接口回调产生接口回调的场景在现实生活中,产生接口回调的场景很简单,比如我主动叫你帮我做一件事,然后你做完这件事之后会通知我,&quo
- 背景在Java中一个回调的操作是一个在一些操作完成之后被传递到另一个函数中并且被执行的函数。一个回调函数既可以被同步或者异步执行。在一个同步
- 看到当上面的对话框弹出时,可以使用命令查看顶层的活动窗口adb shell dumpsys window | findstr mCurren
- 这篇文章主要讲解C#中的泛型,泛型在C#中有很重要的地位,尤其是在搭建项目框架的时候。一、什么是泛型泛型是C#2.0推出的新语法,不是语法糖
- 上一篇说到Springboot整合Netty,自定义协议实现,本文聊一些拆包/沾包问题。拆包/沾包问题TCP是面向字节流的协议,在发送方发送
- 多数据源创建数据库CREATE DATABASE mybatis_plus_1;USE mybatis_plus_1;CREATE TABL
- 补间可以实现两个图形之间颜色、形状、大小、位置等的线性变化。例如A...AB...BC...C,其中A、B、C是三幅图片,两个A的宽分别是1
- 1.重载重载指在一个类中,具有多个相同名称的方法,他们的参数列表却不相同(参数类型不同、参数个数不同甚至是参数顺序不同)重载对返回类型没有要
- 目的:在使用mybatis框架中mapper文件有自动生成,但有时需要自己添加sql语句进行开发,当遇到需要使用 if进行条件判断的时候该怎
- 1. 简单工厂介绍简单工厂有一个具体的工厂类,可以生产不同的产品,属于创建型设计模式。注意:简单工厂模式 不属于23种设计模式之列2. 简单
- 本文实例分析了C#中使用资源的方法。分享给大家供大家参考。具体如下:这里总结一个在C#中如何使用资源的方法如下:方法一、使用本地文件1、将本
- Handler是什么?Handler 是一个可以实现多线程间切换的类,通过 Handler 可以轻松地将一个任务切换到 Handler 所在
- 本文实例讲述了Java实现的计算最大下标距离算法。分享给大家供大家参考,具体如下:题目描述给定一个整形数组,找出最大下标距离j−i, 当且A