6

我需要获取一个 android 活动实例的唯一 ID。我想取activitymanager在日志中写入的字符串(例如:ActivityManager: Activity pause timeout for HistoryRecord{ 450495a0 ...}),但不知道如何获取。

有人知道我怎么能得到这个字符串吗?或者每个活动实例是否有另一个唯一 ID?

4

5 回答 5

9

也许你可以使用 Activity 的 hashCode。

于 2012-06-19T14:25:03.130 回答
3

项目中的每一个地方:

    MainActivity.class.hashCode(); 

在活动中

    this.hashCode();

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

于 2015-05-12T06:44:06.133 回答
3

正如另一个答案中正确指出的那样,操作系统可以重新创建活动,因此使用Activity.hashCode()不是一个可靠的解决方案。此外,整个应用程序进程可以重新创建(例如在权限更改后),这意味着任何运行时/非持久化 ID 都不可信。正确的解决方案是在 期间手动生成唯一 ID onCreate(Bundle)(或从 读取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();
于 2018-06-11T06:15:57.897 回答
1

hashCode()方法中Activity,返回一个android活动实例的唯一id,但getTaskId()不能返回唯一值

于 2012-08-21T03:35:50.803 回答
1

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

如果您想保留更长时间,使用活动的 hashCode 方法不是一个好主意。众所周知,活动可以由操作系统清理。这意味着,当它们被重新创建时,它们可能具有与之前的实例不同的 hashCode。一个解决方案(如果你想保留一个整数作为 id)可能是 getIntent().hashCode()

于 2017-04-27T21:06:27.373 回答