Android檢測(cè)Activity或者Service是否運(yùn)行的方法
需求:假設(shè)我們的APP有3個(gè)頁(yè)面AActivity,BActivity,CActivity,我們的APP需要一直運(yùn)行在前臺(tái)(特殊設(shè)備),要求實(shí)現(xiàn)一個(gè)監(jiān)控服務(wù),來(lái)監(jiān)視APP是否運(yùn)行,如果有3個(gè)頁(yè)面都不運(yùn)行了就說(shuō)明這個(gè)APP已經(jīng)掛掉了,否則說(shuō)明APP在運(yùn)行狀態(tài),不做處理,掛掉之后,我們需要重新啟動(dòng)App來(lái)讓它繼續(xù)處理運(yùn)行狀態(tài),對(duì)外暴露一個(gè)來(lái)停止監(jiān)控服務(wù)的廣播,這樣我們想停止監(jiān)控服務(wù)時(shí),發(fā)送一個(gè)廣播即可。
思路:實(shí)現(xiàn)一個(gè)雙進(jìn)程的監(jiān)控服務(wù),服務(wù)中寫(xiě)一個(gè)定時(shí)器 Timer 來(lái)重復(fù)進(jìn)行檢測(cè)是否正在運(yùn)行,如果否就直接重新啟動(dòng)APP。
1.定義一個(gè)監(jiān)控服務(wù)
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 :)
* 檢測(cè)APP頁(yè)面是否一直運(yùn)行,不運(yùn)行就直接啟動(dòng)
*/
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:殺死自己的進(jìn)程!");
killMyselfPid(); // 殺死自己的進(jìn)程
}
}
};
private Timer timer = new Timer();
private TimerTask task = new TimerTask() {
@Override
public void run() {
checkIsAlive();
}
};
/**
* 檢測(cè)應(yīng)用是否活著
*/
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) { //如果界面掛掉直接啟動(dòng)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: 啟動(dòng)監(jiān)控服務(wù)! ");
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("kill_self");
registerReceiver(broadcastReceiver, intentFilter);
timer.schedule(task, 0, 10000);// 設(shè)置檢測(cè)的時(shí)間周期(毫秒數(shù))
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
/**
* 殺死自身的進(jìn)程
*/
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.注冊(cè)雙進(jìn)程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.檢測(cè)是否活著的工具類(lèi)CheckUtil
public class CheckUtil {
//檢測(cè)service是否在運(yùn)行
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;
}
//檢測(cè)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;
}
/**
* 判斷某個(gè)app進(jìn)程是否在運(yùn)行
*
* @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;
}
/**
* 判斷一個(gè)Activity是否正在運(yùn)行
*
* @param pkg pkg為應(yīng)用包名
* @param cls cls為類(lèi)名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中啟動(dòng)監(jiān)控服務(wù)
Intent intent = new Intent(MainActivity.this, MonitoringService.class);
intent.setAction("android.intent.action.RESPOND_VIA_MESSAGE");
startService(intent);
5.停止監(jiān)控服務(wù)
發(fā)送一個(gè)殺死進(jìn)程廣播即可,action值如下
Intent intent = new Intent();
intent.setAction("kill_self");
sendOrderedBroadcast(intent, null);
好了,今天就分享到這里了。。。
以上這篇Android檢測(cè)Activity或者Service是否運(yùn)行的方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
recycleview實(shí)現(xiàn)拼多多首頁(yè)水平滑動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了recycleview實(shí)現(xiàn)拼多多首頁(yè)水平滑動(dòng)效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
Android Fragment監(jiān)聽(tīng)返回鍵的一種合理方式
這篇文章主要給大家介紹了關(guān)于Android Fragment監(jiān)聽(tīng)返回鍵的一種合理方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
在android中ScrollView嵌套ScrollView解決方案
大家好,眾所周知,android里兩個(gè)相同方向的ScrollView是不能嵌套的,那要是有這樣的需求怎么辦,接下來(lái)為您介紹解決方法,感興趣的朋友可以了解下2013-01-01
Android如何實(shí)現(xiàn)NFC讀取卡片信息
這篇文章主要介紹了Android如何實(shí)現(xiàn)NFC讀取卡片信息問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
AndroidStudio接入U(xiǎn)nity工程并實(shí)現(xiàn)相互跳轉(zhuǎn)的示例代碼
這篇文章主要介紹了AndroidStudio接入U(xiǎn)nity工程并實(shí)現(xiàn)相互跳轉(zhuǎn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12

