Android监听运行应用的任务变化包含Activity及Service
文章目录
- 第一种方案
- 简介
- 定义与作用
- 应用场景
- 代码实现
- 第二种方案
- 简介
- 代码实现
- 测试
- 相关文章
想监听安卓系统中每个应用的运行变化,比如运行到前台,或者退出,或者某个Activity前后台的变化。
使用IActivityManager或IActivityTaskManager这两个都可以实现监听任务运行变化。
第一种方案
简介
IActivityManager是 Android 系统中的一个重要接口,这里主要是使用它实现监听任务变化的。
它与ActivityManagerService,ActivityThread联系很紧密。
定义与作用
IActivityManager是 Android 系统中用于管理活动(Activity)、任务(Task)和应用程序进程等的接口。它提供了一系列方法,允许系统和应用程序之间进行交互,以实现对活动生命周期的管理、任务的操作以及进程的控制等功能。通过这个接口,系统可以协调不同应用程序之间的交互,确保用户界面的流畅切换和多任务处理的高效进行。
应用场景
- 系统层面
当用户在主屏幕上点击一个应用图标时,系统会通过IActivityManager来启动该应用的主活动,创建相应的任务栈,并将活动显示在屏幕上。
系统的多任务管理界面也是通过IActivityManager来获取当前运行的任务列表,以及对任务进行切换、关闭等操作。 - 应用程序层面
应用内进行活动跳转时,实际上也是通过IActivityManager来实现的。例如,一个社交应用从聊天列表界面跳转到具体的聊天详情界面,就是通过IActivityManager来启动相应的聊天详情活动。
应用程序在某些情况下可能需要主动杀死自己的后台进程,或者检测系统中其他应用的进程状态等,这些都可以通过IActivityManager提供的方法来实现。
代码实现
如果直接引用IActivityManager是会报错的
错误: 找不到符号IActivityManager,如下图

需要引入framework.jar
- 工程根目录下创建jar目录,并放入Android SDK编译生成的framework.jar
- app/buiod.gradle中引入framework.jar
implementation fileTree(dir: "libs", include: ["*.jar"])compileOnly files('../jar/framework.jar')
这样代码中就可以引用到IActivityManager了,如下图

3. 使用registerProcessObserver注册回调监听
代码如下
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.IProcessObserver;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;public class AppStackManager {private static final String TAG = "AppStackManager";private IActivityManager mIActivityManager;public void registerProcessObserver() {Log.d(TAG, "registerProcessObserver");if (mIActivityManager == null) {mIActivityManager = ActivityManagerNative.asInterface(ServiceManager.getService(Context.ACTIVITY_SERVICE));}try {// 需要权限<uses-permission android:name="android.permission.SET_ACTIVITY_WATCHER" />mIActivityManager.registerProcessObserver(new IProcessObserver.Stub() {@Overridepublic void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) throws RemoteException {Log.d(TAG, "onForegroundActivitiesChanged: " + pid + " " + uid + " " + foregroundActivities);}@Overridepublic void onForegroundServicesChanged(int i, int i1, int i2) throws RemoteException {Log.d(TAG, "onForegroundServicesChanged: " + i + " " + i1 + " " + i2);}@Overridepublic void onProcessDied(int pid, int uid) throws RemoteException {Log.d(TAG, "onProcessDied: " + pid + " " + uid);}});} catch (Exception e) {e.printStackTrace();}}
}
这种方案获取当前变化的应用的包名不好弄,这里推荐第二种方案。
第二种方案
简介
IActivityTaskManager 是 Android 系统中用于管理任务(Task)和窗口(Window)相关操作的重要接口。这个接口是从 Android 10(API 级别 29)开始引入的。在此之前,与任务和窗口管理相关的功能大多集成在 IActivityManager 中。将任务和窗口管理的功能拆分到 IActivityTaskManager 中,使得系统架构更加清晰,各个模块的职责更加明确,便于维护和扩展。
代码实现
与第一种一样,需要引入framework.jar(这里省略),
使用registerTaskStackListener注册回调进行监听
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
import android.app.TaskStackListener;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;public class AppStackManager {private static final String TAG = "AppStackManager";private IActivityTaskManager mIActivityTaskManager;public void registerTaskStackListener() {Log.d(TAG, "registerTaskStackListener");if (mIActivityTaskManager == null) {mIActivityTaskManager = ActivityTaskManager.getService();}try {// 需要权限<uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />mIActivityTaskManager.registerTaskStackListener(new TaskStackListener() {@Overridepublic void onTaskStackChanged() throws RemoteException {super.onTaskStackChanged();Log.d(TAG, "onTaskStackChanged");}@Overridepublic void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) throws RemoteException {super.onTaskMovedToFront(taskInfo);Log.d(TAG, "onTaskMovedToFront: " + taskInfo.baseActivity.flattenToString());Log.d(TAG, "packageName:" + taskInfo.baseActivity.getPackageName());}@Overridepublic void onTaskMovedToBack(ActivityManager.RunningTaskInfo taskInfo) {super.onTaskMovedToBack(taskInfo);Log.d(TAG, "onTaskMoved:" + taskInfo.baseActivity.flattenToString());}});} catch (Exception e) {e.printStackTrace();}}
}
测试
比如在桌面上打开原生设置时,
回调函数中可以正确打印出其变化,如下图

相关文章
Android监听第三方播放获取音乐信息及包名
Android Framework学习二:Activity创建及View绘制流程
作者:帅得不敢出门
