У меня возник следующий вопрос. Есть достаточно типичная задача — организация фотогалереи. Есть img, в котором нужно менять src. Так вот, возникла следующая проблема: при изменении данного свойства первые несколько раз изображение меняется, после чего исчезает. Поясню: речь идет о приложении для Windows Mobile, поэтому похоже, что заканчивается доступная память. Предыдущие src кешируются и не освобождаются. В пользу этого свидетельствует то, что на различных телефонах возможно различное количество смен свойства src. Как можно избежать расходования памяти на мобильных устройствах?
Большое спасибо за ответ!
Оба способа проверил, но пока что не получилось решить проблему
CS>1) Использовать <picture> элемент вместо <img>. <picture> не кеширует images, предазаначен именно для показа pictures.
После замены img на picture ситуация стала следующей. Если раньше на симуляторе можно было загрузить порядка 4 картинок (в сумме ~150 килобайт), после чего следующие были пустыми, а при возврате на предыдущие эти четыре показывались, то image, действительно, их не кеширует, и в этом случае повторно они не показываются.
Определение глобальной переменной:
dom::element g_photogalleryPicture;
Создание фрейма (однократно):
HELEMENT hPicture;
HTMLayoutCreateElement("picture", L"", &hPicture);
HTMLayoutSetAttributeByName(hPicture, "style", _T("width: 100%; height: auto;"));
HTMLayoutInsertElement(hPicture, g_parent, 0);
g_photogalleryPicture = hPicture;
Обновление картинки (периодическое действие):
wchar_t wImageLink[] = _T("..."); // Здесь из списка берется адрес очередной картинки
g_photogalleryPicture.set_attribute("src", wImageLink);
g_photogalleryPicture.update();
CS>2) Использовать <frame> и загружать в него "<html><body><img src=...></body></html>" через element::load_html() ...
Определение глобальной переменной:
dom::element g_photogalleryImageFrame;
Создание фрейма (однократно):
HELEMENT hFrame;
HTMLayoutCreateElement("frame", L"", &hFrame);
HTMLayoutSetAttributeByName(hFrame, "style", _T("width: 100%; height: 100%"));
HTMLayoutInsertElement(hFrame, g_parent, 0);
g_photogalleryImageFrame = hFrame;
Обновление картинки (периодическое действие):
wchar_t wImageLink[] = _T("..."); // Здесь из списка берется адрес очередной картинки
wchar_t buff[1024];
wsprintf(buff, _T("<html><body><picture src='%ls'/></body></html>"), wImageLink);
w2utf utfBuff = w2utf(buff);
g_photogalleryImageFrame.set_html(utfBuff, utfBuff.length());
Эффект аналогичный. Может быть я неверно применяю дескрипторы и смартпоинтеры? Но ведь по идее в первом варианте меняется лишь атрибут.
Кроме этих способов пробовал и другие:
1. Создавать все картинки галереи сразу, делая видимой в каждый момент времени одну из них. Как показала практика, грузиться начинают сразу все картинки, даже изначально невидимые. Поэтому чтобы расставить точки над i display: none везде поубирал, чтобы просто взглянуть на загрузку галереи как будто просто нужно загрузить все указанные картинки. В результате из, допустим, 15 картинок фактически отобразились около тех же 4. Если не на симуляторе, а на современном телефоне посмотреть, то около 7 картинок — поэтому похоже что дело в памяти.
2. Эксперименторовал с картинками в css, назначая их на дивы. Тоже безрезультатно, несколько кешируются, после этого не грузятся.
3. Пробовал при смене картинки выкидывать из DOM предыдущий элемент и вставлять новый. Тоже не помогло.
Единственное что еще не попробовал — подставлять картинки в base64, но не думаю что это особо хорошая идея
Version language : Русский (Россия)
CompanyName : Terra Informatica Software. Inc.
FileDescription : htmlayout: h-smile core, Windows Mobile wrapper
FileVersion : 3, 3, 2, 1
Подозрительно сие — 150 килобайт картинки это ерунда для эмулятора и современного телефона.
Попробуйте это в sciter сделать или дайте пример проекта.
/ yarus23
Всем спасибо за ответы, вроде бы нащупал откуда грабли.
Прежде всего сделал простейший проект, с простейшим документом:
<html><body><picture style='width: 100%; height: auto;' /></body></html>
Далее записал интересующие проблемные линки в массив:
wchar_t* images[] = { _T("..."), _T("...") };
int imagesCount = sizeof(images) / sizeof(wchar_t*);
int currentImage = 0;
// Обычным образом назначаются после создания документа
dom::element root;
dom::element picture;
и сделал смену картинки по меню (вместо About в простейшем WinMobile приложении):
if (currentImage < imagesCount - 1)
{
wchar_t* link = images[++currentImage];
picture.set_attribute("src", link);
picture.update();
}
Результат — даже на минимальном приложении глюк хорошо воспроизводится — показ нескольких изображений из моей подборки (каждое изображение около 35 килобайт, редко больше!) вызывает залипание дальнейшей смены картинок.
Пошёл дальше: залез на Яндекс.Фотки, выбрал там RSS-поток и покопировал ссылки из него в свой массив. Получилось вроде такого:
wchar_t* images[] = { _T("http://img-fotki.yandex.ru/getx/10000/photohistory.2010.5/16_M"),
_T("http://img-fotki.yandex.ru/getx/10000/photohistory.2010.5/15_M"),
_T("http://img-fotki.yandex.ru/getx/10000/photohistory.2010.5/14_M"),
... }
};
И, о чудо, стало все работать как надо
После такого успеха поменял суффиксы в данных ссылках на XL, чтобы изображение бралось в максимальном качестве. При этом средняя картинка стала около 130 килобайт (каждая). Результат — всё так же работает.
Осталось две версии:
1. Хостинг.
2. Формат файла.
Сейчас разбираюсь в деталях.
Здесь нужно заметить, что хостинг уже был причиной глюков в работе приложения на HTMLayout. Но в тот раз у меня закралось подозрение, что виной тому использованный было по началу gzip. Сейчас получается что не только это. Самое интересное, что сервер, на котором расположены картинки далеко не детский, и в браузере они грузятся чуть быстрее, чем моментально. Любая!
Ладно, настроил на другом сервере (выделенный) каталог с теми же картинками. Что характерно, после этого ситуация значительно улучшилась. Можно просматривать серии из 20 картинок и все ОК.
Но до конца вопрос не решился — в некоторых галереях затыки стабильно происходят, но не 100% детерминированно. Поэтому продолжаю изыскания. Не исключено, что и с форматом файлов что-то не то. А возможно имеет значение порядок следования файлов (чередование соотношений сторон, например). Буду делать серверное перекодирование через Python Image Library. Поэкспериментирую также и с серверами (lighttpd, nginx). Сейчас на скорую руку все крутится из-под Апача.
Как удастся локализовать причину, напишу.