Android 获取当前顶层 Activity 的方法:兼容 Q 及以下版本
Android 获取当前顶层 Activity 的方法:兼容 Q 及以下版本
在 Android 开发中,有时需要获取当前处于顶层的 Activity,例如在后台服务中需要获取当前 Activity 的信息,或者在某个特定场景下需要判断当前 Activity 是否为指定的 Activity。
本文将介绍如何通过 Java 代码获取 Android 设备当前处于顶层的 Activity,并提供一个兼容 Android Q 及以下版本的通用方法。
方法介绍
获取当前 Activity 的方法主要有两种:
-
Android Q 及以上版本: 可以直接使用
ActivityManager.getRunningTaskInfo方法获取当前运行的任务栈信息,其中topActivity字段即为当前顶层 Activity 的类名。 -
Android Q 以下版本: 由于
ActivityManager.getRunningTaskInfo方法在 Android Q 以下版本不可用,需要使用反射机制获取ActivityManagerService对象的mTopResumedActivity字段,该字段保存了当前顶层 Activity 的对象。
兼容性代码
以下代码提供了一个兼容 Android Q 及以下版本的通用方法,可以获取当前 Activity 的类名:
import android.app.ActivityManager;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TopActivityUtil {
/**
* 获取最顶部的 Activity
*
* @param context 上下文
* @return 最顶部的 Activity 类名
*/
public static String getTopActivity(Context context) {
String topActivity = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Android Q 及以上版本可以使用 ActivityManager.getRunningTaskInfo 获取最顶部的 Activity
ActivityManager.RunningTaskInfo runningTaskInfo = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getRunningTasks(1).get(0);
topActivity = runningTaskInfo.topActivity.getClassName();
} else {
// Android Q 以下版本需要使用反射获取 ActivityManagerService 的 mTopResumedActivity 字段
try {
// 获取 ActivityManagerService 对象
Class<?> activityManagerNativeClass = Class.forName("android.app.ActivityManagerNative");
Method getDefaultMethod = activityManagerNativeClass.getDeclaredMethod("getDefault");
getDefaultMethod.setAccessible(true);
Object activityManagerService = getDefaultMethod.invoke(null);
// 获取 mTopResumedActivity 字段
Field mTopResumedActivityField = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mTopResumedActivityField = activityManagerService.getClass().getDeclaredField("mTopResumedActivity");
} else {
mTopResumedActivityField = activityManagerService.getClass().getDeclaredField("mFocusedActivity");
}
mTopResumedActivityField.setAccessible(true);
// 获取 mTopResumedActivity 字段的值
Object topResumedActivity = mTopResumedActivityField.get(activityManagerService);
topActivity = topResumedActivity.getClass().getName();
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | NoSuchFieldException e) {
Log.e("TopActivityUtil", "getTopActivity: ", e);
}
}
return topActivity;
}
}
代码使用
// 获取当前 Activity 的类名
String topActivity = TopActivityUtil.getTopActivity(this);
// 打印当前 Activity 的类名
Log.d("MainActivity", "Top Activity: " + topActivity);
注意
- 使用反射获取系统内部字段可能会存在兼容性问题,建议在使用前进行充分的测试。
- 获取顶层 Activity 的操作需要相应的权限,例如
android.permission.GET_TASKS权限。
希望本文能够帮助您理解如何获取当前顶层 Activity,并提供一个可行的解决方案。
原文地址: https://www.cveoy.top/t/topic/oFvA 著作权归作者所有。请勿转载和采集!