Поиск сообщества
Показаны результаты для 'памяти'.
Найдено: 436 результатов
-
Математика - математикой, мне вот интересно, что с картинками? потому как если их грузить сразу в ListView, то памяти не напасёшься, получается их надо подтягивать по мере надобности, поэтому и попросил вариант с картинками. понятно, что с аватарами легкими все будет тип-топ, интересуют картинки.
-
вторая версия демо -работа над ошибками -устранил утечки памяти -расширил функционал -добавил картинки -совместимость с Android Приложил EXE и APK Скорее всего, для 100500 записей не потянет, т.к. слишком много арифметики для раскладки каждого элемента на каждом итеме, но для сотни - хватает. ListViewTest2.7z pasFiles.rar
-
Евгений, спасибо громадное за код!!! Красиво и лаконично! Но под Rio всё равно крэшится с ошибкой, если приложение закрывать раньше, чем успевают загрузиться фотки: Project Test21.exe raised exception class ENetHTTPClientException with message 'Error receiving data: (12017) Операция отменена'. Поправил вот так: procedure TForm1.ClearListViewAndCancelAsynchronousRequests(); var I: Integer; begin FListViewUpdating := True; // Запрещаем продолжать загружать фотки (если ещё не успели загрузиться все) while FAsyncResultList.Count > 0 do // Дожидаемся окончания выполнения всех IAsyncResult.Cancel, несмотря на асинхронность begin for I := FAsyncResultList.Count - 1 downto 0 do if Assigned(FAsyncResultList.Items) and (not FAsyncResultList.Items.IsCompleted) then FAsyncResultList.Items.Cancel else FAsyncResultList.Delete(I); // Заодно удаляем элементы (раннее не удалялись - утечка памяти) end; ListView1.Items.Clear; FListViewUpdating := False; end; ===== Тоже, кстати, пару раз поймал ошибку в TMonitor и в TDictionary. Выяснил, что возникает из-за обращения к элементам списка в LoadImage, когда их уже нет. Пофиксил так (отмечено синим): procedure TForm1.LoadImage(const AItem: TListViewItem; const AListItemImage : TListItemImage); var K: Integer; // Анонимная процедура захватывает локальную переменную, а не обращается к AItem, которой уже может не быть в момент _окончания_ скачивания фотки AAsyncResult: IAsyncResult; begin if Not Assigned(AItem) or Not Assigned(AListItemImage) then Exit; if AItem.Data['ImageState'].AsInteger <> ListViewItemImageEmpty then Exit; if AItem.Data['ImageURL'].AsString.IsEmpty then Exit; AItem.Data['ImageState'] := ListViewItemImageLoading; K := AItem.Index; // Запоминаем индекс в локальную K, которая уйдёт в анонимку (время жизни K > времени жизни анонимки) FAsyncResultList.Items[K] := FHTTPClient.BeginGet( procedure (const ASyncResult: IAsyncResult) var AHTTPResponse: IHTTPResponse; begin if ASyncResult.IsCancelled then Exit; try AHTTPResponse := THTTPClient.EndAsyncHTTP(ASyncResult); if Not Assigned(AHTTPResponse) then Exit; if AHTTPResponse.StatusCode <> 200 then Exit; except Exit; end; TThread.Synchronize(Nil, procedure begin if FListViewUpdating then // Выходим, так как внутри анонимной процедуры AItem или AListItemImage - не сброшены в nil, хотя их уже может и не быть Exit; // Кстати, наверное, правильнее было бы вместо проверки FListViewUpdating использовать и/или условие: if ASyncResult.IsCancelled then Exit; ? if Not Assigned(AItem) or Not Assigned(AListItemImage) then Exit; AListItemImage.BeginUpdate; AListItemImage.Bitmap := TBitmap.Create; AListItemImage.Bitmap.LoadFromStream(AHTTPResponse.ContentStream); AListItemImage.EndUpdate; AItem.Data['ImageState'] := ListViewItemImageLoaded; FAsyncResultList.Items[K] := nil; // Наверное, это присвоение лучше вытащить наверх, перед проверкой всех условий? Ведь фотка скачалась успешно... Или не надо? end ); end, AItem.Data['ImageURL'].AsString ); end; ==== Прогонял много раз, клацал по кнопке один и много раз и закрывал сразу приложение, ошибки пока больше не появлялись... Тьфу-тьфу-тьфу....
-
Вот тут лучше перестраховаться и взять за правило принцип "Любое обращение к адресному пространству другого потока выполнять потокобезопасными способами". Потому как даже чтение может привести к непредсказуемым результатам - читаете вы данные, строку к примеру из другого потока, прочитали половину, а тот поток в это время перезаписал содержимое ячеек памяти, и вы после этого читаете оставшуюся половину. Вместо ожидаемых данных получаете черте что. Это грубый пример конечно.
-
где-то лезете в участок памяти, куда бы не следовало лезть!
-
Обычная фотография на современных моделях устройств может быть очень большой. Например, на телефоне с 10 мега пиксельной камерой, фотография будет около 10 Mb. Устройства на базе Андроид выделяют меньше оперативной памяти устройствам. Поэтому физически бывает, что более слабые устройства не способны загрузить картинку в память по причине нехватки памяти, выделенной приложению. Google официально предлагает грузить в ваше приложение сжатые версии изображений. Чтобы в ваше приложение получать сокращенное изображение, в действии TakePhotoFromCameraAction есть свойства MaxWidth и MaxHeight для указания максимально допустимого разрешения фотографии.
-
Я не о том. Например есть 1000 итемов, у каждого картинка по 20 кбайт, в памяти она хранится как несжатый массив байтов и может расжиреть до 100 кбайт на картинку. Получается только под картинки сожрется 100 мбайт памяти. Короче говоря, у меня после вывода 100 картинок начинаются глюки. Картинки чернеют, надписи на итемах превращаются в снег. Как сокращаю до 50 сразу все нормально. Как то так. Я на это наткнулся на стандартном варианте работы с картинками.
-
Для полноценной работы вам нужно добавить параметры в вызов (иначе вы не узнаете дал ли пользователь разрешение или нет) PermissionsService.RequestPermissions([FPermissionWrite, FPermissionRead], nil); Вот так: PermissionsService.RequestPermissions([FPermissionWrite, FPermissionRead], PermissionRequestResult, ExplainReason); PermissionRequestResult - это обработка ответа пользователя procedure TForm.PermissionRequestResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>); begin if (Length(AGrantResults) = 2) and (AGrantResults[0] = TPermissionStatus.Granted) and (AGrantResults[1] = TPermissionStatus.Granted) then begin // Ура! Пользователь дал разрешение на оба наших запроса. Выставялем глобальные флаги (к примеру) которые сигнализируют что можно читать/писать карту памти end else TDialogService.ShowMessage('Не возможно продолжить работу, требуемые разрешения не получены') end; И ExplainReason - если пользователь сдуру не дал разрешение, то вам нужно объяснить ему что без этого приложение работать не будет. procedure TForm.ExplainReason(Sender: TObject; const APermissions: TArray<string>; const APostRationaleProc: TProc); begin TDialogService.ShowMessage('Приложению нужен доступ к карте памяти для таких то целей, иначе приложение не сможет работать. Зайдите в настроки Андроид и дайте разрешение на доступ', procedure(const AResult: TModalResult) begin APostRationaleProc; end) end;
- 4 ответа
-
- delphi rio
- 2019
-
(и ещё 2 )
C тегом:
-
Поставьте бряк внутри метода _ReciveMessage и удивитесь - в каком потоке он вызывается. Ну или напишите if TThread.Current.ThreadID<>MainThreadID then // мог слегка ошибиться с наименованиями переменных - пишу по памяти, но вроде это они и есть. Алярма!!! (тут что-нибудь сигнализирующее что всё неправильно). Включая режим буквоедства: смените названия на ReceiveMessage и PackedNumber. Глаз цепляется
-
Я написала несколько отдельных программ в RAD Studio 10.1 Berlin. Одну программу в виде меню которая запускает эти программы. Необходимо идентифицировать эти программы как программы написанные мной. Проверка посходит путем считывания label если он соответствует ожиданиям, то программа-меню записывает в label другой текст и форма на которой находится label считывает его и если все верно показывает компоненты которые содержит. Программа-меню свое свойство visible:=false; Как только программа которая была вызвана исчезает из памяти свойство программа-меню visible:=true идентифицирует и запускает вот эта: Код: unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,ShellAPI, FMX.Edit, FMX.Controls.Presentation, FMX.StdCtrls,ShellAPI; type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.Button1Click(Sender: TObject); begin ShellExecute(1, nil, PChar(Edit1.Text), nil, nil, 0) end; end. Но пока она только умеет только запускать, а инфицировать не можетвторая тоже самое только без вызывающей функции Код: unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,ShellAPI, FMX.Edit, FMX.Controls.Presentation, FMX.StdCtrls,ShellAPI; type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} end.
-
Зря Вы TPurgatory угробили Простой пример: при потере фокуса закрывается всплывающее меню и разрушается всплывающая форма с этим меню, на OnClick всплывающего меню повешен обработчик, в обработчике возникает исключение которое приводит к появлению окошка с сообщением об ошибке появление окна с сообщением об ошибке закрывает и разрушает контекстное меню получается внутри метода объекта мы совершенно незаметно для себя уничтожили этот объект и на выходе из обработчика OnClick мы уже попадаем ... куда? В код разрушенного объекта. Может там остались старые данные и всё отработает нормально, а может там уже данные другого объекта, или еще какой мусор и приложение аварийно выкидывается из памяти. Как оно в итоге получится зависит от везения и фазы луны. Подобные ситуации могут возникнуть и в других, менее очевидных случаях. Так что будьте бдительны.
-
3000 это то что было у меня. но причем тут 50 кб? 3000 это чисто текстовые позиции, картинки через кеш и подгрузку были. поэтому мне и нравится подход к этому делу андроидного грида, он каждый раз при появлении нового итема грида делает запрос на заполнение данными. как итем пропал с экрана то он удаляется из памяти. ну как я понял его работу.
-
[TMultiView] Правки стандартного примера MultiViewDemo
Равиль Зарипов (ZuBy) опубликовал вопрос в TMultiView
Доработал чуть CustomPresentation из демо 1) убрал баг с утечкой памяти было так с включенным ReportMemoryLeaksOnShutdown := true; 2) неточное отображение на форме, не по центру было стало 3) при открытой MV закрыть программу, утечка памяти ReportMemoryLeaksOnShutdown := true; 4) Добавил события OnShown, OnHidden MultiView.zip-
- CustomPresentation
- TMultiView
-
(и ещё 1 )
C тегом:
-
Все ваши проблемы решаются добавлением трех строчек в код: Перед началом работы, сразу задаем количество строк Memo.Lines.Capacity:=1000000; Мемо сразу зарезервирует в своем TStringList нужный объем. Это позволит сократить накладные расходы на добавление в несколько раз. Перед добавлением строк в Memo обязательно делаем Memo.BeginUpdate; Это отключит перерисовку и другие операции. После добавления строк в Memo обязательно делаем Memo.EndUpdate; Это отрисует все изменения которые мы произвели. Вот итоговый код (в форме еще глобальный счетчик FLinesCounter : Integer;): procedure TForm1.FormCreate(Sender: TObject); Var I : Integer; begin Memo.Lines.Capacity:=1000000; Timer.Interval:=10; FLinesCounter:=1; Memo.BeginUpdate; for I := 1 to 10000 do begin Memo.Lines.Add('Это тест ' + FLinesCounter.ToString); Inc(FLinesCounter); end; Memo.EndUpdate; end; procedure TForm1.Button1Click(Sender: TObject); begin Timer.Enabled:=True; end; procedure TForm1.Log(const AMessage : String); const ConsMaxLogSize = 50000; begin Memo.BeginUpdate; // while Memo.Lines.Count > ConsMaxLogSize do // Memo.Lines.Delete(0); Memo.Lines.Add(AMessage); Memo.GoToTextEnd; Memo.EndUpdate; end; procedure TForm1.TimerTimer(Sender: TObject); begin Log('Это тест ' + FLinesCounter.ToString); Inc(FLinesCounter); end; Код добавляет в Мемо 10 тысяч строк за примерно пол секунды. И добавление по таймеру 100 строк в секунду отнимает примерно 0% процессорного времени. Все будет работать без тормозов до разумного предела, при очень больший количествах строк вы столкнетесь с тормозами выделения памяти приложению, тут нужно будет использовать иные механизмы.
-
свой класс на дженерике с ключом и картинкой, с проверкой занимаемой памяти и освобождением старых при превышении определенной границы. НО!! Все это будет все равно тормозить на больших объемах. Ибо все в листвью через попу. Что бы определить видим или нет итем, листвью пробегается по всем итемам, и вычисляет их высоту и зная позицию скрола вычисляет видим или нет итем. чем больше полей, тем больше вычилений при каждом движении.
-
Приветствую всех. Создаю мобильное приложение для Андроид. Основа - TTabControl на главной форме с двумя вкладками, заголовки вкладок скрыты. На первой вкладке список задач, которые может выполнять приложение. При выборе задачи анимарованно (используя SetActivTabWithTransition) открывается вторая вкладка с элементами управления для выбранной задачи. Элементы управления для каждой задачи реализованы на отдельных формах: на форму кладется TVertScrollBox (Align = Client), а в него уже необходимые элементы управления. Когда пользователь выбирает задачу, то нужная форма создается динамически, родитель TVertScrollBox у этой формы меняется на вторую вкладку TTabControl и вызывается SetActivTabWithTransition. Когда пользователь жмет кнопку "Назад" (аппаратную или программную), то, опять же анимированно, открывается первая вкладка (со списком задач), родитель у TVertScrollBox обратно меняется на созданную ранее форму, форма удаляется оператором delete. Подскажите, не будет ли при таком подходе утечек памяти? На Windows уверен, что не будет, а вот на Андроид не знаю... Кроме этого, целесообразно ли применять форму? Или лучше использовать фрейм? Или же изложенный мной подход вообще не заслуживает реализации? ?
-
External exception C000001D между Form.OnCreate и Form.OnShow
hippocamus опубликовал вопрос в Отладка
Поставил Delphi 10.3 Rio, так как в нём, вроде бы, наконец исправили очень важный для меня момент - Z-Order для нативных контролов. При запуске проекта - вылет с указанной ошибкой после выполнения всех инструкций FormCreate и до выполнения первой команды FormShow. Не думаю, что это связано со сменой среды, так как давно не запускал основной проект на 10.2.3, а теперь проверить не получится, т.к. предыдущую версию снёс. Нашёл, что C000001D - это STATUS_ILLEGAL_INSTRUCTION. В MSDN про нее написано - "Attempting to execute an instruction code not defined by the processor". И обычно подобная гадость случается при попытке повторного освобождения памяти. Что же такое может происходить между этими двумя событиями? (Удалял и один обработчик и второй, перекидывал инструкции между ними как угодно - всё равно эта же ошибка). -
если я в Bitmap присоединил картинку то она будет висеть в памяти и если записей около 1000 то памяти выкушивается прилично. способ ее уменьшить? при потери видимости убивать картинку при возобновлении опять присоединять. если есть другой способ буду рад услышать.
-
Здравствуйте коллеги. Написал приложение с необходимостью разрешений LocalSensor, MediaLibrary, Read/Write Storage и т.д. С АПИ Левел 14 все работало на ура. Дошел до выкладки на Play Market и уперся в API level 26. Нашел решение для Tokio (у меня Berlin) - KastriFree ( https://www.delphiworlds.com/2018/06/targeting-android-8-and-higher-continued/) попробовал реализовать как в статье и все равно не работает, приложение просто закрывается сразу после открытия. Ошибка I/O 17 в первом же месте обращения к файлам на карте памяти. Если в манифесте указать таргетлевел 14, то все нормально запускается и работает. Но такое приложение не пускает фильтр Play Marketa. Что делать? Как быть? И еще, думал скачать RAD 10.3 Community, получил на почту ключ, но на этапе установки после ввода ключа пишет, что не может обратиться к серверу. Если кто знает ответ - дайте ссылку, пожалуйста.
-
1. для упрощения кода работы с JSON давно можно использовать сложные пути ABase64:=JSON.GetValue<string>('body.nextStep.pdf'); 2. ну нельзя так: AStreamSource.WriteBuffer(Pointer(ABase64)^, Length(ABase64) * 2); так безопасней AStreamSource:=TBytesStream.Create(TEncoding.UTF8.GetBytes(ABase64)); 3. И сохранять лучше сразу в TFileStream - меньше расход памяти 4. не забываем finally Free (их выше нету)... хоть оно и может AUTOREFCOUNT (а может и нет!), но правила хорошего тона никто не отменял
- 4 ответа
-
- delphi 10.1 fmx
- delphi 10.1 fmx android
- (и ещё 1 )
-
TListBox [TListBox] Как отобразить итемы в виде панелей?
enatechno ответил uakmal вопрос в Стилизация
Согласен, что TGridPanelLayout проигрывает по памяти. Но за счет того, что листбокс занимается выгрузкой и загрузкой при скролле, мы и видим его притормаживание. Соответственно, автор должен решить, готов ли он платить памятью за плавный скролл? Для экономии памяти не обязательно грузить все панельки в TGridPanelLayout сразу. Достаточно загрузить порцию для 1.5-2 экранов (в указанном автором примере это будет 9-18 шт), а потом при скролле вниз подгружать по 6-9 шт. Автор привел пример с категориями ('Десерты', 'Салаты', ...). Это значит, что при перемещениях по категориям и подкатегориям, скорее всего, ему не придется подгружать большие порции для первых нескольких экранов. Конечно же было проще анализировать задачу, если б автор указал среднее количество панелек для каждой категории/подкатегории. Для данной задачи важен также и размер картинок в панельках. Повторю, я видел работающий пример. Все работало довольно шустро и плавно для 200 панелек в одной категории. (попробуйте сделать такое в листбокс и посмотрите на плавность скролла). У листбокса для этой задачи (категории/подкатегории) есть "подводные камни". Например: невозможно в событии OnItemClick перезаполнить содержимое этого листбокс без AV. Т.к. после этого обработчика в TCustomListBox.MouseUp (хе7) происходит попытка обратится к несуществующему Item-у: if Assigned(OnItemClick) then OnItemClick(Self, Item); P := Item.ScreenToLocal(LocalToScreen(TPointF.Create(X, Y))); // тут AV т.к. нет проверки, существует ли Item (а он будет уничтожен при перезаполнении листбокс) Item.MouseUp(Button, Shift, P.X, P.Y); Полностью поддерживаю. Но судя по теме, автор еще не настолько опытен в FMX, чтоб рекомендовать ему ListView для решения данной задачи. -
Способы, думаю есть, зависит от того какой именно функционал реализован в вашем приложении. Т.е. по сути всё сводится к оптимизации логики и кода. К сожлению пособов оптимизировать программу "Hello world!" весьма не много... Тут дело в том, что программа, написаная по FMЧ тянет за собой весь фреймворк, который необходим ей для запуска. Он помещается в памяти при запуске приложения, даже если оно "пустое". Оно сарзу будет занимть 40-50 метров. под андроид так и того больше. Поэтому, если и существует возможность оптимизации расхода памяти под FMX, то боюсь в основном только на стороне разработчиков фрейма...
-
Добрый день! Решил покопаться в своей старой спрайтовой игрушке, чтобы освежить в памяти знания и состряпать что-нибудь новое. Возникли сомнения, нормально ли сделано графическое отображение, можно ли доработать. Все спрайты в дизайнтайме распиханы по Timagelist-ам. На старте приложения я загружаю битмапы из имэджлистов в свои обджектлисты, подгоняя под нужный размер. MeduzasBitmpAr : array [1..numofMeduzas] of TObjectList<Tbitmap>; Дальше рисую по таймеру в основном окне игры Tpaintbox.OnPaint: В принципе, даже на слабеньких телефончиках, всё вроде бодро. Но может, опытные товарищи чего подскажут, а то я 3ий день в собственном соку варюсь, ничего толкового.
-
Стандартная практика при работе с WinAPI - после выделения памяти под структуру заполнить ее нулями.
-
Разрешения для приложения не вступают в силу на Android
WebPuper опубликовал вопрос в Развертывание приложений
Столкнулся со странным. Для приложения в манифесте установлено <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> но после загрузки из Play Market галочка для использования "Память" не активна. Чтобы приложение имело доступ к памяти приходится ставить ее в ручную. Причем если я веду отладку по USB, то все в порядке. Почему разрешения не вступают в силу?