安卓实现切换后台监控


上周四下午同事提了一个需求,想要监控app切换到后台和息屏的事件。原因是因为用户在使用app时大多数时候不会去主动关闭app,又因为我们的app和远程服务器有一个数据池的长连接,所以用户不主动退出就导致了连接数只增不减,最终down掉。所以他想在上述的两种事件中强制app退出。

其实我有点怀疑服务器传输堵塞可能不是这个问题造成的,连接池都会有超时熔断的操作,应该不会有连接不收回的情况。但是他既然有这个需求,那就先试着实现吧。

分析

想要实现后台切换监控,第一个想到的就是从activity生命周期下手,对于Lifecycle大家应该都很熟悉了,从一个a到另一个a经历了几个过程呢?

假设有两个页面 ab
有些人觉得跳转过程是下面这样:

展示a界面:a.onCreat -> a.onStart -> a.onResume
跳转b界面:a.onPause -> a.onStop -> b.onCreat -> b.onStart -> b.onResume

其实跳转时的触发顺序是这样:

跳转b界面:a.onPause -> b.onCreat -> b.onStart -> b.onResume -> a.onStop

看到区别了吧?也就是说,一个界面在展示时总会触发onStart,但是触发onStop时却是在第二个页面触发onStart之后

换句话说:只有在手机息屏和app切换到后台时onStart和onStop的触发数目才能相等。

由此咱们可以得出一种方案,通过计数来判断当前app的状态。

具体的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class MyLifecycleHandler implements Application.ActivityLifecycleCallbacks {//通过继承截获activity的周期方法

private static int appCount = 0;//计数器
private String TAG = "MyLifecycleHandler";
private final static int STOP_APP = 333;//标志
private final static long DELAY_TIME = 2*60*60*1000;//停止时间 单位:ms

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

}

@Override
public void onActivityStarted(Activity activity) {
appCount++;
Log.e(TAG,"切到前台");
uiHandler.removeMessages(STOP_APP); // 删除通知
}

@Override
public void onActivityResumed(Activity activity) {

}

@Override
public void onActivityPaused(Activity activity) {

}

@Override
public void onActivityStopped(Activity activity) {
appCount--;
if(appCount==0){
Log.e(TAG,"切到后台");
uiHandler.sendEmptyMessageDelayed(STOP_APP,DELAY_TIME);
}
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

}

@Override
public void onActivityDestroyed(Activity activity) {

}

private Handler uiHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case STOP_APP:
Log.e(TAG,"杀死进程");
ActivityManager activityManager = (ActivityManager) ItcmorApplication.getContext().getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.AppTask> appTaskList = activityManager.getAppTasks();
for (ActivityManager.AppTask appTask : appTaskList) {
appTask.finishAndRemoveTask();
}
System.exit(0);
System.gc();
break;
}
}
};
}

在监控到两种事件发生后,会发出一个通知,2小时后杀死进程。开始的时候这里直接调用System.exit(0)发现没什么用,后来明白这个exit只是退出虚拟机,页面并没有退出,后来参照了网上的做法获取activity栈,遍历移除。

算是完成这个需求了。但是这个退出有点暴力,如果各位朋友有更加优雅的退出方法请联系我哦~~

-------------本文结束,感谢您的阅读-------------

本文标题:安卓实现切换后台监控

文章作者:饭饭君~

发布时间:2018年11月26日 - 17:29

最后更新:2019年04月23日 - 10:51

原始链接:https://yangcf.github.io/2018/11/26/安卓实现切换后台监控/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

如果我的文章有帮助到你,欢迎打赏~~
0%