Android Activity 的唯一标识符

7

我需要获取Android活动实例的唯一标识符。我想要获取活动管理器在日志中写入的字符串(例如:ActivityManager: Activity pause timeout for HistoryRecord{450495a0 ...}),但是我不知道如何获取它。

有人知道我如何获取此字符串吗?还是每个活动实例都有另一个唯一标识符?


定义唯一性的域。 - m0skit0
抱歉,我不了解您的意思。 - anel
1
唯一在哪里?设备中唯一?地球上唯一?宇宙中唯一? - m0skit0
5个回答

9

也许你可以使用Activity的hashCode。


获取ActivityManager的字符串会很好,但哈希码当然也可以胜任。如果我无法获取此特定字符串,则将使用哈希码,但其他字符串将使我的调试更容易。 - anel

6
如其他答案所指出的那样,活动可以被操作系统重新创建,因此使用“Activity.hashCode()”不是可靠的解决方案。此外,整个应用程序进程可以在权限更改后重建,这意味着任何运行时/非持久化ID都不能被信任。正确的解决方案是在“onCreate(Bundle)”期间手动生成唯一的ID(如果存在,则从“savedInstanceState”中读取),并在“onSaveInstanceState(Bundle)”期间保存它。
另一个问题是生成真正唯一的ID。最简单和最可靠的解决方案是保留一个静态计数器,但由于应用程序进程可能会死亡,因此需要更多的关注。
为了将样板代码减少到最小限度,我已经组合了一个专业类:
public class ActivityUUID {

    private static final String INSTANCE_DATA_ID = "BwsKCwYBDg8GAQ4LBAgAAA"; // NOTE Any globally unique ID
    private static final String UUID_NODE_ID = "a";
    private static final long INVALID_UUID = 0;

    private static long _lastActivityUUID = INVALID_UUID; // NOTE All activity callbacks are guaranteed to be made from UI thread, so no synchronization is required
    private static SharedPreferences _persistentData;

    private final long _uuid;

    public ActivityUUID(Context context, Bundle savedInstanceState) {
        _uuid = readUUID(context, savedInstanceState);
    }

    public long get() {
        return _uuid;
    }

    public void onSaveInstanceState(Bundle outState) {
        outState.putLong(INSTANCE_DATA_ID, _uuid);
    }

    private static long readUUID(Context context, Bundle savedInstanceState) {
        long result = (savedInstanceState != null) ? savedInstanceState.getLong(INSTANCE_DATA_ID, INVALID_UUID) : INVALID_UUID;
        return (result != INVALID_UUID) ? result : generateUUID(context);
    }

    private static long generateUUID(Context context) {
        if (_persistentData == null) {
            _persistentData = context.getSharedPreferences(INSTANCE_DATA_ID, Context.MODE_PRIVATE);
            _lastActivityUUID = _persistentData.getLong(UUID_NODE_ID, INVALID_UUID);
        }

        long result = ++_lastActivityUUID;
        if (result != INVALID_UUID) {
            _persistentData.edit().putLong(UUID_NODE_ID, result).apply();
        } else {
            throw new RuntimeException("You have somehow managed to create a total of 9223372036854775807 activities during lifetime of your app! =)");
        }
        return result;
    }

}

使用方法非常简单:

private ActivityUUID _activityUUID;

@Override
public final void onCreate(Bundle savedInstanceState) {
    _activityUUID = new ActivityUUID(this, savedInstanceState);
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    _activityUUID.onSaveInstanceState(outState);
}

// ...somewhere else in the code
long activityUUID = _activityUUID.get();

2

在您的项目中无处不在:

    MainActivity.class.hashCode(); 

在Activity中

    this.hashCode();

您甚至可以从上下文中获取hashCode


2

我知道这个问题有点过时了,但出于某些原因我需要它。

如果你想要长时间保留活动(Activity)的hashCode方法,那么使用它并不是一个好主意。我们都知道,操作系统可以清理活动(Activity)。这意味着,当它们重新创建时,它们可能具有与之前实例不同的hashCode。解决这个问题的方法(如果你想要一个整数作为ID)可以是getIntent().hashCode()。


OP 需要每个活动实例一个唯一的 ID,所以我不明白为什么使用 hashCode 是不好的。 - Piotr Aleksander Chmielowski

1

hashCode() 方法在 Activity 中,它返回一个 Android 活动实例的唯一标识符,但是 getTaskId() 无法返回唯一值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接