java - 如何在 ViewModel android 中使用 mBagOfTags?

标签 java android kotlin viewmodel package-private

我有一个实现 Closeable 接口(interface)的对象,并希望在我的 ViewModel 清除时调用 close() 方法。我知道要实现 ViewModel 的 onCleared 方法,但我想在 ViewModel 中使用 mBagOfTags。 mBagOfTags 处理可关闭对象(在 clear 方法中调用 close 方法)并且不想在 ViewModel 中创建新的 map 对象。我如何使用 ViewModel 的 mBagOfTags ??

mBagOfTags及其在ViewModel中的成员函数是package Private access modifer。

这是android团队开发的ViewModel类。

package androidx.lifecycle;

public abstract class ViewModel {
// Can't use ConcurrentHashMap, because it can lose values on old apis (see b/37042460)
@Nullable
private final Map<String, Object> mBagOfTags = new HashMap<>();
private volatile boolean mCleared = false;

/**
 * This method will be called when this ViewModel is no longer used and will be destroyed.
 * <p>
 * It is useful when ViewModel observes some data and you need to clear this subscription to
 * prevent a leak of this ViewModel.
 */
@SuppressWarnings("WeakerAccess")
protected void onCleared() {
}

@MainThread
final void clear() {
    mCleared = true;
    // Since clear() is final, this method is still called on mock objects
    // and in those cases, mBagOfTags is null. It'll always be empty though
    // because setTagIfAbsent and getTag are not final so we can skip
    // clearing it
    if (mBagOfTags != null) {
        synchronized (mBagOfTags) {
            for (Object value : mBagOfTags.values()) {
                // see comment for the similar call in setTagIfAbsent
                closeWithRuntimeException(value);
            }
        }
    }
    onCleared();
}

/**
 * Sets a tag associated with this viewmodel and a key.
 * If the given {@code newValue} is {@link Closeable},
 * it will be closed once {@link #clear()}.
 * <p>
 * If a value was already set for the given key, this call does nothing and
 * returns currently associated value, the given {@code newValue} would be ignored
 * <p>
 * If the ViewModel was already cleared then close() would be called on the returned object if
 * it implements {@link Closeable}. The same object may receive multiple close calls, so method
 * should be idempotent.
 */
@SuppressWarnings("unchecked")
<T> T setTagIfAbsent(String key, T newValue) {
    T previous;
    synchronized (mBagOfTags) {
        previous = (T) mBagOfTags.get(key);
        if (previous == null) {
            mBagOfTags.put(key, newValue);
        }
    }
    T result = previous == null ? newValue : previous;
    if (mCleared) {
        // It is possible that we'll call close() multiple times on the same object, but
        // Closeable interface requires close method to be idempotent:
        // "if the stream is already closed then invoking this method has no effect." (c)
        closeWithRuntimeException(result);
    }
    return result;
}

/**
 * Returns the tag associated with this viewmodel and the specified key.
 */
@SuppressWarnings({"TypeParameterUnusedInFormals", "unchecked"})
<T> T getTag(String key) {
    if (mBagOfTags == null) {
        return null;
    }
    synchronized (mBagOfTags) {
        return (T) mBagOfTags.get(key);
    }
}

private static void closeWithRuntimeException(Object obj) {
    if (obj instanceof Closeable) {
        try {
            ((Closeable) obj).close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
}

我的 ViewModel 在另一个包中。

最佳答案

您可以将文件的包设置为与 ViewModel 包相同。写入文件的第一行:“package androidx.lifecycle”

关于java - 如何在 ViewModel android 中使用 mBagOfTags?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69971368/

相关文章:

java - 投票应用程序的安全性

Java HttpsURLConnection 响应 JSON 数组

java - 如何检查主教的空对角线?

java - 未正确计算通过 Java 代码添加到组的用户的访问权限

kotlin - Kotlin 内联文档的正确名称是什么?

types - Kotlin 可以在类文件中发出 JSR-305 注释吗

android - 使用 List 查询 Realm

安卓 : save/open picture taken from camera intent

android - 我如何在 Volley 库中获取 Inputstream 作为响应

list - 在 Kotlin 中对 MutableList 中的数据进行排序