Android 获取当前顶层 Activity 的方法:兼容 Q 及以下版本

在 Android 开发中,有时需要获取当前处于顶层的 Activity,例如在后台服务中需要获取当前 Activity 的信息,或者在某个特定场景下需要判断当前 Activity 是否为指定的 Activity。

本文将介绍如何通过 Java 代码获取 Android 设备当前处于顶层的 Activity,并提供一个兼容 Android Q 及以下版本的通用方法。

方法介绍

获取当前 Activity 的方法主要有两种:

  1. Android Q 及以上版本: 可以直接使用 ActivityManager.getRunningTaskInfo 方法获取当前运行的任务栈信息,其中 topActivity 字段即为当前顶层 Activity 的类名。

  2. 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,并提供一个可行的解决方案。

Android 获取当前顶层 Activity 的方法:兼容 Q 及以下版本

原文地址: https://www.cveoy.top/t/topic/oFvA 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录