Ответ 1
Вы можете использовать Parcel.writeValue
для сортировки общего объекта с нулевым значением.
в отношении моего примера кода вниз, что мне делать, если одна переменная Locable имеет значение null? В примере, теперь, если l.getZoom() возвращает null, я получил исключение NullPointerException.
@Override
public void writeToParcel(Parcel parcel, int arg1) {
parcel.writeInt(count);
for(Locable l:locableArr){
parcel.writeInt(l.getOriginId());
parcel.writeInt(l.getLocableType());
parcel.writeInt(l.getZoom());
parcel.writeDouble(l.getLatituda());
parcel.writeDouble(l.getLongituda());
parcel.writeString(l.getTitle());
parcel.writeString(l.getSnipet());
}
}
Спасибо!
Вы можете использовать Parcel.writeValue
для сортировки общего объекта с нулевым значением.
Большинство кодов сериализации, которые я видел, использует либо флаги, чтобы указать наличие/отсутствие значения ИЛИ предшествует значению с помощью поля count (например, при написании массивов), где поле счетчика просто установлено на ноль, если значение вообще не существует.
Изучение исходного кода основных классов Android показывает такой код (из класса сообщений):
if (obj != null) {
try {
Parcelable p = (Parcelable)obj;
dest.writeInt(1);
dest.writeParcelable(p, flags);
} catch (ClassCastException e) {
throw new RuntimeException(
"Can't marshal non-Parcelable objects across processes.");
}
} else {
dest.writeInt(0);
}
или это (из класса Intent):
if (mCategories != null) {
out.writeInt(mCategories.size());
for (String category : mCategories) {
out.writeString(category);
}
} else {
out.writeInt(0);
}
Мое предложение: В вашем коде, если нет функциональной разницы между "zoom == null" и "zoom == 0", тогда я бы просто объявил масштаб как примитив (int
вместо Integer
) ИЛИ инициализируйте его в ноль в конструкторе и убедитесь, что вы никогда не устанавливали его в null (тогда вы можете быть уверены, что он никогда не будет пустым, и вам не придется добавлять специальный код для работы с этим в ваших методах сериализации/десериализации).
Я использую класс Parcelable
с полями Integer
и Boolean
, и эти поля могут быть пустыми.
У меня возникли проблемы с использованием общего метода Parcel.writeValue
, особенно когда я пытался его прочитать через Parcel.readValue
. Я продолжал получать исключение во время выполнения, в котором говорилось, что он не может определить тип разделяемого объекта.
В конечном счете, я смог решить проблему, используя Parcel.writeSerializable
и Parcel.readSerializable
с типом cast, так как оба Integer
и Boolean
реализуют интерфейс Serializable. Методы чтения и записи обрабатывают значения null
для вас.
Это решение, с которым я столкнулся, чтобы безопасно писать строки:
private void writeStringToParcel(Parcel p, String s) {
p.writeByte((byte)(s != null ? 1 : 0));
p.writeString(s);
}
private String readStringFromParcel(Parcel p) {
boolean isPresent = p.readByte() == 1;
return isPresent ? p.readString() : null;
}