Идентификатор экземпляра Google
Выпущен на I / O 2015; на Android требуется игровые сервисы 7.5.
https://developers.google.com/instance-id/ https://developers.google.com/instance- id / guide / android-implementation
InstanceID iid = InstanceID.getInstance( context ); // Google docs are wrong - this requires context
String id = iid.getId(); // blocking call
Кажется, Google намерен использовать этот идентификатор для идентификации установок на Android, Chrome и iOS.
Он идентифицирует установку, а не устройство, но опять же, ANDROID_ID (который является принятым ответом) теперь больше не идентифицирует устройства. С помощью среды ARC для каждой установки создается новый ANDROID_ID (подробности здесь ), как и этот новый идентификатор экземпляра.
Преимущества идентификатора экземпляра
Мне кажется, что Google намерен для этого (с указанием ваших установок), он является кросс-платформенным и может использоваться для ряда других целей (см. ссылки выше).
Если вы используете GCM, то в конечном итоге вы необходимо использовать этот идентификатор экземпляра, потому что вам нужно его, чтобы получить токен GCM (который заменяет старый идентификатор регистрации GCM).
Недостатки / проблемы
В текущей реализации ( GPS 7.5) идентификатор экземпляра извлекается с сервера, когда ваше приложение запрашивает его. Это означает, что вызов выше - это блокирующий вызов - в моем ненаучном тестировании он занимает 1-3 секунды, если устройство находится в сети, и 0,5-1,0 секунды, если он отключен (предположительно, это то, как долго он ждет, прежде чем отказаться от случайный идентификатор). Это было протестировано в Северной Америке на Nexus 5 с Android 5.1.1 и GPS 7.5.
Если вы используете идентификатор для своих целей - например. аутентификация приложения, идентификация приложения, GCM - я думаю, что это 1-3 секунды может быть неприятным (в зависимости от вашего приложения, конечно).
В Java 8 появилась возможность передать объект пересечению типов, добавив несколько границ . Поэтому в случае сериализации можно написать:
Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!");
И лямбда автоматически становится сериализуемой.
Очень уродливый литой. Я предпочитаю определять расширение Serializable для функционального интерфейса, который я использую
Например:
interface SerializableFunction<T,R> extends Function<T,R>, Serializable {}
interface SerializableConsumer<T> extends Consumer<T>, Serializable {}
, тогда метод, принимающий лямбда, может быть определен как таковой:
private void someFunction(SerializableFunction<String, Object> function) {
...
}
и вызывая функцию, вы можете передать свою лямбду без какого-либо уродливого броска:
someFunction(arg -> doXYZ(arg));
Если вы хотите переключиться на другую структуру сериализации, например Kryo , вы можете избавиться от множественных границ или требования, которые должен реализовывать реализованный интерфейс Serializable
. Подход к
InnerClassLambdaMetafactory
, чтобы всегда генерировать код, необходимый для сериализации LambdaMetaFactory
во время десериализации Подробности и код см. в этом сообщении в блоге
Такая же конструкция может использоваться для ссылок на методы. Например, этот код:
import java.io.Serializable;
public class Test {
static Object bar(String s) {
return "make serializable";
}
void m () {
SAM s1 = (SAM & Serializable) Test::bar;
SAM s2 = (SAM & Serializable) t -> "make serializable";
}
interface SAM {
Object action(String s);
}
}
определяет лямбда-выражение и ссылку на метод с сериализуемым типом цели.