如何将Bundle转换为PersistableBundle?

时间:2017-07-18 22:14:34

标签: android bundle shortcut job-scheduling

API21发布了PersistableBundle,这是系统为各种目的保留的捆绑包(JobScheduler jobsShortcutInfos等)。我想要一种简单的方法将旧代码中存在的Bundle转换为PersistableBundle ...我该怎么办?

3 个答案:

答案 0 :(得分:4)

从API26开始,没有办法轻易做到这一点,你必须手动验证这些值是否兼容:

private boolean bundleCanBePersisted(final Bundle extras) {
    if (extras == null) {
        return true;
    }

    Set<String> keys = extras.keySet();
    Iterator<String> it = keys.iterator();
    boolean allExtrasPersistable = true;
    while (it.hasNext()) {
        String key = it.next();
        boolean isPersistable = isPersistable(extras.get(key));

        if (!isPersistable) {
            LOGGER.warning("Non persistable value in bundle. " + bundleItemToString(key, extras));
        }

        allExtrasPersistable &= isPersistable;
    }
    return allExtrasPersistable;
}

/**
 * These are all the values that can be put into a PersistableBundle.
 */
private boolean isPersistable(final Object o) {
    return o == null
            || o instanceof PersistableBundle
            || o instanceof String
            || o instanceof String[]
            || o instanceof Boolean
            || o instanceof Boolean[]
            || o instanceof Double
            || o instanceof Double[]
            || o instanceof Integer
            || o instanceof Integer[]
            || o instanceof Long
            || o instanceof Long[];
}

private String bundleItemToString(final String key, final Bundle bundle) {
    Object value = bundle.get(key);
    Class<?> valueClazz = null;
    if (value != null) {
        valueClazz = value.getClass();
    }
    return String.format("[%s = %s (%s)]", key, value, valueClazz);
}

答案 1 :(得分:4)

这是一个实际将Bundle转换为PersistableBundle并返回的实用程序:

/**
 * Creates a new {@link Bundle} based on the specified {@link PersistableBundle}.
 */
public static Bundle toBundle(PersistableBundle persistableBundle) {
    if (persistableBundle == null) {
        return null;
    }
    Bundle bundle = new Bundle();
    bundle.putAll(persistableBundle);
    return bundle;
}

/**
 * Creates a new {@link PersistableBundle} from the specified {@link Bundle}.
 * Will ignore all values that are not persistable, according
 * to {@link #isPersistableBundleType(Object)}.
 */
public static PersistableBundle toPersistableBundle(Bundle bundle) {
    if (bundle == null) {
        return null;
    }
    PersistableBundle persistableBundle = new PersistableBundle();
    for (String key : bundle.keySet()) {
        Object value = bundle.get(key);
        if (isPersistableBundleType(value)) {
            putIntoBundle(persistableBundle, key, value);
        }
    }
    return persistableBundle;
}

/**
 * Checks if the specified object can be put into a {@link PersistableBundle}.
 *
 * @see <a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/PersistableBundle.java#49">PersistableBundle Implementation</a>
 */
public static boolean isPersistableBundleType(Object value) {
    return ((value instanceof PersistableBundle) ||
            (value instanceof Integer) || (value instanceof int[]) ||
            (value instanceof Long) || (value instanceof long[]) ||
            (value instanceof Double) || (value instanceof double[]) ||
            (value instanceof String) || (value instanceof String[]) ||
            (value instanceof Boolean) || (value instanceof boolean[])
    );
}

/**
 * Attempts to insert the specified key value pair into the specified bundle.
 *
 * @throws IllegalArgumentException if the value type can not be put into the bundle.
 */
public static void putIntoBundle(BaseBundle baseBundle, String key, Object value) throws IllegalArgumentException {
    if (value == null) {
        throw new IllegalArgumentException("Unable to determine type of null values");
    } else if (value instanceof Integer) {
        baseBundle.putInt(key, (int) value);
    } else if (value instanceof int[]) {
        baseBundle.putIntArray(key, (int[]) value);
    } else if (value instanceof Long) {
        baseBundle.putLong(key, (long) value);
    } else if (value instanceof long[]) {
        baseBundle.putLongArray(key, (long[]) value);
    } else if (value instanceof Double) {
        baseBundle.putDouble(key, (double) value);
    } else if (value instanceof double[]) {
        baseBundle.putDoubleArray(key, (double[]) value);
    } else if (value instanceof String) {
        baseBundle.putString(key, (String) value);
    } else if (value instanceof String[]) {
        baseBundle.putStringArray(key, (String[]) value);
    } else if (value instanceof Boolean) {
        baseBundle.putBoolean(key, (boolean) value);
    } else if (value instanceof boolean[]) {
        baseBundle.putBooleanArray(key, (boolean[]) value);
    } else if (value instanceof PersistableBundle) {
        baseBundle.putAll((PersistableBundle) value);
    } else {
        throw new IllegalArgumentException("Objects of type " + value.getClass().getSimpleName()
                + " can not be put into a " + BaseBundle.class.getSimpleName());
    }
}

您可以在this gist中找到完整的课程和单元测试。

答案 2 :(得分:-1)

将表单捆绑包转换为PersistableBundle

Bundle b = new Bundle();
PersistableBundle pb = new PersistableBundle(b);

从PersistableBundle转换为Bundle

PersistableBundle pb = new PersistableBundle();
Bundle b= new Bundle();
b.putAll(pb);