Перейти к содержанию
Fire Monkey от А до Я

Поиск сообщества

Показаны результаты для 'памяти'.

  • Поиск по тегам

    Введите теги через запятую.
  • Поиск по автору

Тип контента


Форумы

  • Общие вопросы
    • Анимация
    • Графика
    • Стили
    • Базы данных и REST
    • Компоненты
    • Положение, размеры, выравнивание
    • Работа с текстом
    • Приложение и формы
    • Отладка
    • Развертывание приложений
    • Вопросы по языку Object Pascal и RTL
    • Общая информация о TControl
    • События
    • Прочие вопросы
  • Вопросы по платформам
    • Android
    • iOS
    • OSX
    • Windows
    • Windows Phone
    • Linux
  • Вопросы по использованию RAD Studio
    • Лицензирование
    • Сборка проектов
    • Multi-Device Designer
    • Редактор кода
    • Вопросы
  • Обучение
    • Основная информация
    • Вопросы
    • Отзывы
  • Поиск специалистов по FireMonkey
    • Консультации
    • Ищу подрядчика
  • Дополнительные ресурсы по FireMonkey
    • Сторонние компоненты
    • Приложения, написанные с использованием FireMonkey
    • Примеры
    • Руководства
    • Шаблоны
    • Статьи и заметки
    • Информация о версиях RAD Studio
    • Новости
  • Организация работы данного форума

Поиск результатов в...

Поиск контента, содержащего...


Дата создания

  • Начало

    Конец


Дата обновления

  • Начало

    Конец


Фильтр по количеству...

Регистрация

  • Начало

    Конец


Группа


AIM


MSN


Сайт


ICQ


Yahoo


Jabber


Skype


StackOverflow


Защита от ботов


Город


Интересы

  1. Самым прямым. Чтобы менеджер памяти единый был. Тогда можно спокойно использовать GetMem/FreeMem и т.п. Например, приложение может быть, на Delphi, а DLL на Builder-e, внутри которой нужно динамические массивы создавать. Конечно, если используются различные среды, то дельфовые строки и стандартные процедуры выделения/освобождения памяти использовать не стоит. ТС свой сценарий использования dll не описал, поэтому можно пофантазировать...
  2. Подскажите, как можно вывести в ListBox весь список папок и файлов из корня внутренней памяти?
  3. При создании такого сервиса какой наиболее правильный вариант выбрать? Intent Local, Intent Remote? Сервис как и приложение должно быть Андроид 64? Хотелось бы как у правильных плееров, при свернутом приложении или блокированном экране - музыка играла. При выгруженном пользователем приложения из памяти, музыка прекращала воспроизведение. P.S. А вообще выяснилось, что и пустая служба без музыки у меня убивается. В чем причина не понятно: http://fire-monkey.ru/topic/6863-android-services/#comment-39981
  4. Еще на форуме нашла цитату Ярослава, но примера к ней не нашла: Вообще можно напрямую вызывать методы сервиса. Так как они находятся в одной области памяти и имеют прямой доступ друг к другу. Для этого достаточно создать TLocalServiceConnection, установить связь с сервисом через BindService и получить прямой доступ к сервису через TLocalServiceConnection.LocalService
  5. Попробовал с процедурой KillMe из этого модуля в FormClose. Результат - мне не помогло. Может этот способ помогает с закрытием приложений, но мои проблеммы,связанные с запуском, остались. Я тут обнаружил, что одно приложение занимает около 70МБ RAM. На смартфоне с 512 МБ RAM виснет при запуске ощутимо чаще, чем на планшете с 1024 МБ. (интересно, что было бы на девайсе с 256 МБ...). То есть возникла логическая цепочка по поводу слишком большых требований к RAM. Но изменение настроек LargeHeap в VersionInfo на True не помогает,(хотя и не хочется трогать этот параметр). Поэтому все так же теряюсь в догадках по поводу причины сбоев. Но простейшие приложения всегда запускаются без проблем. В этой связи, если все же догадки по поводу памяти верны, возникает такой вопрос: В приложении используются PNG изображения в качестве ресурсов. Сами по себе файлы, в которых всего несколько цветов, весят очень мало. Но, насколько я понимаю, при загрузке в tbitmap на каждый пиксель выделяется 4 байта (3 на цвета и 1 на прозрачность), то есть в памяти это изображение png хранится как полноцветный bmp с альфа-каналом? Если так, то на изображения уходит очень много памяти. Поэтому вот собственно и вопрос: есть ли способ хранить в RAM исходный png, а не BMP? Хотя, как я понимаю, изображение, закодированное таким образом, нельзя редактировать. Но неужели во всех приложениях с графикой в памяти все изображения хранятся как битмапы? Прошу тех, кто владеет темой, объяснить сей момент.
  6. То ли я вас не понял то ли вы меня. Я сделал так, что в памяти загружены только несколько картинок одновременно, а точнее ровно столько сколько видно итемов. Допустим высота контрола 1000, Высота итема 100. Так вот в памяти всегда загружено именно 11 картинок как бы вы не скролили вниз или вверх количество кушаемой памяти практически не меняется. Если итем не виден то картинка для него выгружается из памяти вообще. Ограничение такого подхода только в том что картинки для этого контрола должны храниться локально в файлах на устройстве.
  7. Может быть попробовать оптимизировать потребление RAM приложением? Тогда увеличится вероятность остаться в памяти при сворачивании. К слову на устройстве под управлением Android 6.0 c 3 ГБ памяти ничего не закрывается. Но при небольшом количестве открытых приложений (камера, мессаджеры и прочие стандартные программы), объем свободной памяти уменьшается до 1 ГБ.
  8. Запускаю ваш проект на XE7 под Widnows 64Bit. Рост памяти не вижу. Специально сделал частоту генерации данных, 10 раз в секунду. Прикладываю скриншоты анализа используемой памяти. Как видно на графиках, рост памяти не наблюдается на графике, постоянен и равен 33,4 Мб. При удалении TeeChart все корректно происходит. Память занимаемая самим компонентом отдается менеджеру памяти Delphi, а не системе. А менеджер делфи будет держать ее у себя для новых ваших объектов. Поэтому вы не увидите на системном графике, что память отдана обратно приложением операционной системе.
  9. Два года назад написал аппликацию для Анроида и тут появилась необходимость починить баг. А я уже забыл как создать АПК без подключенного аппарата. Ткните носом или напомните мне процедуру а то у меня провал в памяти.
  10. хммм, оказалось есть одна неприятная вещь, при переходе на 10.3 и отказе от Application.processmessages при первичном старте компоненты не сортируются. Дебаг показал, что у них у всех при первом запуске (Form1.RoomsScrollBox.Content.Children.Items[element] as TEssence).Position.Y = 0; то есть, я делаю вывод, что пока элементы не отобразились TAlignLayout.top - еще не сработало, они как-бы подвешены в памяти и сортировка поэтому не срабатывает. Ест какие-нибудь идеи кроме таймера как отрисовать элементы? Сейчас создание и дальнейшая сортировка срабатывают по form.show.
  11. Здравствуйте! Подскажите пожалуйста как понять и искать эти утечки памяти:
  12. Все зависит от решаемых задач. Но если мы говорим о хранилище значений, то такой вариант хорош. Плюсы: Строгая типизация. Мы будем обращаться и работать со значением конкретного конечно типа без дополнительных приведений Минусы: Реализация дженериков порождает отдельный тип класса для каждого параметра шаблона. Поэтому количество памяти будет задействовано больше (если есть критерий по памяти). Например, если вы хотите хранить значения 10 типов, то вы получите на выходе 10 классов. С учетом того, что как-то так складывается, что в Delphi разработчики не особо заботятся о количестве потребляемой памяти, то этот вариант будет чаще использоваться. Другой вариант, использования RTTI для хранения значения с использованием TValue. TSimpleObject = class(TObject) constructor Create(wrappedPrimitive : TValue); property Value : TValue read SetValue; Плюсы: Один класс на все типы Недостатки: Требуется дополнительный код по проверки и приведению TValue к нужному типу. Снижается скорость обращения. P.S. Был еще вариант с Variant, но я бы его назвал устаревшим, после появления TValue.
  13. ну и пускай тормозит не обязательно что бы сразу появлялась. время будет подумаю над реализацией. но замысел такой. в итем добавлять картинку когда он еще например за 10 итемов до показа и удалять картинку если он уже после 10 итема показа. добавлять картинку можно через поток. правда работа с картинками обязательно должна быть синхронизированна с основным, но все равно. и даже если пользователь на какое то время увидит белый квадрат а потом в нем картинку, ничего страшного не произойдет. за то не будет лишнего жора памяти на портативных устройствах. на компе конечно все красиво и память можно не экономить. а вот на андроиде даже с гигом памяти уже нужна экономия, так как в памяти сидит не только твоя программ но и куча других а свопа подкачки нет. да и на андроиде веселый эффект с рассыпающимися надписями на пиксели и снегом вместо картинок не очень как то смотрится.
  14. вот здесь у вас ошибка... вы пишите за пределы массива ArrayDetails... его размер = 2 (Length(ArrayDetails)=2)... следующая строка после цикла for на второй итерации обращается к 4-му элементу массива, которого нет... запись происходит в область памяти занятой другим объектом (возможно TCanvas вашего TImage.Bitmap)... такие ошибки сложно найти и последствия от них непредсказуемы... поэтому, если делаете такие ошибки включите галочку в опциях проекта Range checking = true, тогда будете сразу получать ошибку ERangeError при обращении к элементам массива за его пределами...
  15. Здравствуйте Уважаемые. Подскажите пожалуйста как устранить ошибку (скрин в приложении) на строке TNetworkState.Create в приложении для OS Android в Delphi 10.3. на телефоне 10-й Андроид. Процедура такая: //Поделиться сохранённым файлом procedure TForm_DB_BOKA_Glavn.ButtonПоделитьсяClick(Sender: TObject); var NS: TNetworkState; begin NS := TNetworkState.Create; if not NS.IsConnected then begin ShowMessage('Нет подключения к интернету.'); Abort; end else begin if NS.IsWifiConnected then ShowMessage('Подключено через WiFi'); if NS.IsMobileConnected then ShowMessage('Подключено через WWAN'); if FileExists(TPath.GetDownloadsPath+'/Модель_'+ComboBoxВсеМодели.Selected.Text+'.txt') then begin ShareFile(TPath.GetDownloadsPath+'/Model_'+ComboBoxВсеМодели.Selected.Text+'.txt', 'Это файл карточки модели '++ComboBoxВсеМодели.Selected.Text); Application.ProcessMessages; end else ShowMessage('Файл '+TPath.GetDownloadsPath+'/Model_'+ComboBoxВсеМодели.Selected.Text+'.txt'+' не найден.'); end; end; Процедура ShareFile такая: procedure ShareFile(aFileName, aComment : String); {$IFDEF ANDROID} var Intent : JIntent; uri : Jnet_Uri; AttachmentFile: JFile; S : String; {$ENDIF ANDROID} begin {$IFDEF ANDROID} Intent := TJIntent.Create; Intent.setAction(TJIntent.JavaClass.ACTION_SEND); Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK); S:=TPath.GetFileName(aFileName); Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(aComment)); Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(aComment)); AttachmentFile := TJFile.JavaClass.init(StringToJString(aFileName)); Uri := TJnet_Uri.JavaClass.fromFile(AttachmentFile); Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, TJParcelable.Wrap((Uri as ILocalObject).GetObjectID)); Intent.setType(StringToJString('text/plain')); // Intent.setDataAndType(StrToJURI('file:' + TPath.Combine(TPath.GetSharedDownloadsPath, 'picture.png')), StringToJString ('image/png')); SharedActivity.startActivity(Intent); {$ENDIF ANDROID} end; При этом разрешение к памяти у телефона есть на это приложение. Интересно что в другом моём приложении где те же процедуры всё работает. Но перед тем как это 2-е приложение я запустил после обновления 9-го Андроида на 10-й система спросила сама разрешения а в этом нет. Я вручную разрешал. Может тут дело не в разрешениях???
  16. в общем, попробовал переписать код с использованием TFDMemTable: var mtL, mtR, mt: TFDMemTable; d,d1,d2: tdatetime; s,id: string; c:char; idR, m, line, status, InA, InC, OutA, OutC, h:int64; begin c:=chr(39); mtL:=TFDMemTable.Create(nil); mtR:=TFDMemTable.Create(nil); FDQueryL[0].Connection:=FDConnectL[0]; FDQueryR[0].Connection:=FDConnectL[0]; FDQueryL[0].FetchOptions.Unidirectional := False; FDQueryR[0].FetchOptions.Unidirectional := False; FDQueryL[0].Sql.Text := 'SELECT * FROM source_table;'; FDQueryL[0].Open; FDQueryL[0].FetchAll; FDQueryR[0].Sql.Text := 'SELECT * FROM destination_table;'; FDQueryR[0].Open; FDQueryR[0].FetchAll; // mtL.Data:=FDQueryL[0].Data; // mtR.Data:=FDQueryR[0].Data; mtL.CopyDataSet(FDQueryL[0], [coStructure, coRestart, coAppend] ); mtR.CopyDataSet(FDQueryR[0], [coStructure, coRestart, coAppend] ); mtL.Open; mtR.Open; mtL.DisableControls; mtR.DisableControls; with mtR do begin LogChanges := False; FetchOptions.RecsMax := 300000; //Sample value ResourceOptions.SilentMode := True; UpdateOptions.LockMode := lmNone; UpdateOptions.LockPoint := lpDeferred; UpdateOptions.FetchGeneratorsPoint := gpImmediate; end; mtR.BeginBatch; idR:=0; d:=EncodeDate(2019,6,1)+EncodeTime(1,0,0,0); d1:=d; while d<now do begin for line := 4 to 20 do begin //выбитаем все что в 1 часе mtL.Filtered := False; //не обращайте внимания на кривизну кода фильтра mtL.Filter := '(ID_CL='+inttostr(line)+') AND '+ '(TimeFrom >= '+c+DateTimeToStr(d)+c+ ') AND ('+ 'TimeFrom < '+c+FormatDateTime('dd.mm.yyyy h:mm:ss', IncSecond(d, 3599))+c+')'; mtL.Filtered := true; //считаем сумму минут m:=0; InA:=0; InC:=0; OutA:=0; OutC:=0; mtL.First; while (not mtL.Eof) do begin m:=m+SecondOfTheDay(mtL.Fields[2].AsDateTime)-SecondOfTheDay(mtL.Fields[1].AsDateTime); InA:=InA + mtL.Fields[4].AsInteger; InC:=InC + mtL.Fields[5].AsInteger; OutA:=OutA + mtL.Fields[6].AsInteger; OutC:=OutC + mtL.Fields[7].AsInteger; Application.ProcessMessages; mtL.Next; end; //выставляем статус пакету if m=3600 then status:=1 else status:=0; if m<>0 then //добавляем записб в приемник begin with mtR do begin Append; Fields[0].AsInteger := idR; Fields[1].AsDateTime := d; Fields[2].AsDateTime := d+EncodeTime(1,0,0,0); Fields[3].AsInteger := line; Fields[4].AsInteger := InA; Fields[5].AsInteger := InC; Fields[6].AsInteger := OutA; Fields[7].AsInteger := OutC; Post; end; idR:=idR+1; end; end; d:=RecodeMilliSecond(d, 0); d:=IncSecond(d,3600); Application.ProcessMessages; end; mtR.EndBatch; mtL.EnableControls; mtR.EnableControls; FDQueryR[0].Close; FDQueryR[0].CopyDataSet(mtR); FDQueryR[0].Open; mtL.Free; mtR.Free; Результата нет - памяти жрет 170 Мб (вместо 5), а работает так же медленно. помогите. что я делаю не так?
  17. Просветите, пожалуйста, насчет IOHandler. Я явно его не задаю, однако код IdTCPClient.IOHandler.Write(s, s.Size, True); отрабатывает без ошибок и корректно. Нужно его задавать явно? И еще на сервере ошибка происходит при закрытии формы на коде if Assigned(IdTCPServer) then IdTCPServer.Active := False; а именно на IdTCPServer.Active := False, поскольку сам объект существует. (ошибка обращения к памяти, посмотрел по отладчику пару раз проходит по exception и в конце концов AV). Если убрать вообще остановку сервера, то при закрытии ошибок нет. Интересно как в этом случае насчет утечки памяти?
  18. Все что есть на экране - это отображение чего-то в памяти. например (я в С не очень, но по смыслу поймете) var ListAll, ListSelected: TObjectList<TFoodMenuItem>; ListAll := TObjectList<TFoodMenuItem>.Create(True); // все меню ListSelected := TObjectList<TFoodMenuItem>.Create(False); // отобранные в заказ пункты //в OnClick нам дается Item. по индексу этого item мы берем объект из ListAll и заносим в ListSelected; listSelected.add( ListAll[index] ); этот пример корявый и не учитывает количества и т.д. но общий смысл именно такой. По индексу в листе работаем с объектом в памяти P.S. если честно, то имеющийся чек какой-то совсем никакой. я бы его поменял на простой собственный image
  19. Добрый день! есть приложение под андроид на 10.3 рио. Изображение с Камеры выводится на одну из закладок табконтрола. Когда с неё пользователь уходит - выключаю камеру (свойство Active в false). Когда возвращается - включаю. Если примерно раз 40 уйти с этой закладки и вернуться - приложение вылетает по непонятной ошибке. Вероятно камеракомпонент какой-то мусор за собой в памяти оставляет. попробовал ее динамически создавать, когда заходишь на эту закладку и уничтожать, когда уходишь с неё. Все работает, но баг с вылетом приложения остался. Может сталкивался кто? каки есть мысли у уважаемого сообщества? Как этот баг победить? есть ли альтернативы? держать камеру все время включённой - негуманно по отношению к аккумулятору (
  20. Столкнулся с похожей проблемой. Зависать FreeLibrary может если в dll в секции финализации какого-то модуля есть что-то что не положено делать в DLLMain, а делать там не положено очень много чего. Очевидное решение вызвать всю финализацию до выгрузки библиотеки. Это можно сделать если собрать dll как bpl пакет, это будет такая же dll, но у нее будут экспортироваться функции Initialize и finalize, об этом как раз есть в цикле статей из предыдущего совета. Мне помогло, но не понравилось что в bpl суется много всего и размер библиотеки сильно вырастает. Если bpl не подходит вот еще несколько костылей 1) Загрузить dll из памяти, не средствами винды а самостоятельно, примеров в интернете куча, в этом случае DllMain вызывается не загрузчиком винды (со своими локами системных структур и дедлоками), а нашим кодом который ничего не блокирует, соответственно все проходит гладко. У меня такой способ заработал. Не на всех dll такое заработает, зависит от полности эмуляции загрузчика винды, на обычной форме сработал самый простой вариант c адаптацией под Delphi 2010. 2) На стэковерфлоу у человека похожая проблема и ему помогла загрузка и выгрузка dll из секции инициализации/финализации хоста (не проверял, может и перевел не верно что он там пишет) 3) Я попробовал эмулировать вызов FinalizeUnits, тоже сработало, правда используются хаки: { Модуль позволяет решить проблему с зависанием при выгрузки dll с FMX формой. Модуль нужно подключить самым первым в dpr файле, до подключения любых файлов с FMX, и вызвать функцию FinalizeAllExceptSystemUnits непосредственно перед выгрузкой dll через FreeLibrary. Например ваша dll экспортирует функцию уничтожения формы, которую вызывает хост перед выгрузкой, например procedure Done; stdcall; begin try //Уничтожим форму FreeAndNil(Form1); //Произведем финализацию модулей которая должна быть выполнена //в FreeLibrary, но все зависает FinalizeAllExceptSystemUnits; //Освобождаем GDI именно после финализации FMX if Assigned(GenericSansSerifFontFamily) then GenericSansSerifFontFamily.Free; if Assigned(GenericSerifFontFamily) then GenericSerifFontFamily.Free; if Assigned(GenericMonospaceFontFamily) then GenericMonospaceFontFamily.Free; if Assigned(GenericTypographicStringFormatBuffer) then GenericTypographicStringFormatBuffer.free; if Assigned(GenericDefaultStringFormatBuffer) then GenericDefaultStringFormatBuffer.Free; GdiplusShutdown(gdiplusToken); except on E: Exception do OutputDebugString(PChar(E.Message)); end; end; author: Виктор Федоренков email: victor.fedorenkov@gmail.com skype: victor_fedorenkov } unit suEmulFinalizeUnitsForUnloadDllUnit; interface uses Windows, SysUtils; procedure FinalizeAllExceptSystemUnits; implementation var _IsFinalizedThisUnit: Boolean = False; //Получение структуры PackageInfo нашего приложения //В System она находится в переменной InitTable, но не видна из других модулей function GetInitTable: PackageInfo; var Lib: PLibModule; Offset: LongWord; TypeInfo: PPackageTypeInfo; begin Result := nil; Lib := LibModuleList; if not Assigned(Lib) then Exit; //Если загружено несколько модулей (BPL пакетов), то выходим, //я не изучал как работает механизм загрузки/выгрузки BPL, поэтому на всякий //случай выходим if Assigned(Lib^.Next) then Exit; Typeinfo := Lib^.TypeInfo; if Assigned(TypeInfo) then begin //Мы имеем TPackageTypeInfo //Теперь по нему можно получить PackageInfo //Воспользуемся особенностями компилятора. //В IDA видно, что ссылка TypeInfo указывает на середину структуры //PackageInfo программы //Поэтому для того что бы вычислить PackageInfo нужно вычесть из адреса //TypeInfo смещение этого поля Offset := LongWord(@PackageInfoTable(nil^).TypeInfo); Result := PackageInfo(PByte(TypeInfo) - Offset); end; end; //Проведем финализацию всего кроме RTL procedure FinalizeAllExceptSystemUnits; var P: Pointer; Count: Integer; OldProtect: LongWord; LExitProc: procedure; InitTable: PackageInfo; Table: PUnitEntryTable; begin while ExitProc <> nil do begin @LExitProc := ExitProc; ExitProc := nil; LExitProc; end; InitTable := GetInitTable; if not Assigned(InitTable) then Exit; Table := InitTable^.UnitInfo; if not Assigned(Table) then Exit; //Мы не можем получить доступ к количеству инициализированных модулей, поэтому //будем работать из расчета что были инициализированы все модули. //Ведь так и есть, инициализирована только часть модулей может быть если //при нициализации произошло исключние в одном из модулей, но тогда будет //запущена финализация всего и видимо библиотека не будет загружена Count := InitTable^.UnitCount; //Разрешаем изменять структуру в которой хранятся ссылки на инициализаю/финализацию всех юнитов //для того что бы затирать уже вызваные секции финализации if not VirtualProtect(Table, SizeOf(PackageUnitEntry) * Count, PAGE_READWRITE, OldProtect) then Exit; try //Вызываем секции финализации пока не будет вызвана секция этого модуля //Так как этот модуль указан первым в dpr файле, то перед ним останется //только системные модули (менеджер памяти, sysutils) которые и без того //нормально финализируются в dll, и их работа нужна что бы отработать //выгрузку dll while not _IsFinalizedThisUnit do begin Dec(Count); //Получим указатель на секцию финализации модуля P := Table^[Count].FInit; //Удалим из структуры указатель на эту функцию что бы родной механизм //финализации повторно не начал ее выгружать Table^[Count].FInit := nil; if Assigned(P) and Assigned(Pointer(P^)) then asm //Похоже какой-то баг компилятора в 10.1 Berlin, и вызов финализации //через TProc(P)(; как это сделано в оригинальной System.FinalizeUnits падает, //поэтому вызываем ассемблером call [p]; end; end; except FinalizeAllExceptSystemUnits; //Пробуем финализировать другие модули raise; end; end; initialization finalization //Выставим флаг что прошла финализация модуля _IsFinalizedThisUnit := True; end. Интересно услышать комментарий спецов по последнему способу, может я что-то не учел
  21. Регистрируем намерение через файл манифеста (ниже для файлов с типом xml). Для Android 3.2 адекватнее работал второй фильтр: <activity … <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="file" /> <data android:mimeType="text/xml" /> <data android:mimeType="application/xhtml+xml" /> </intent-filter> <!-- Для 3.2 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="file" /> <data android:mimeType="*/*" /> <data android:host="*" /> <data android:pathPattern=".*\\.xml" /> <data android:pathPattern=".*\\..*\\.xml" /> <data android:pathPattern=".*\\..*\\..*\\.xml" /> <data android:pathPattern=".*\\..*\\..*\\..*\\.xml" /> <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.xml" /> </intent-filter> Регистрируем свой обработчик события для на событие смены состояния приложения: procedure TForm1.FormCreate(Sender: TObject); var ApplicationService: IFMXApplicationEventService; begin if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, ApplicationService) then ApplicationService.SetApplicationEventHandler(ApplicationEventChanged); end; Оформляем обработчик. Получение файла можно перенести в Form1.onCreate, но я для экспериментов с activity делал тут: function TForm1.ApplicationEventChanged(AAppEvent: TApplicationEvent; AContext: TObject): Boolean; var intent : JIntent; fileFullPath : String; begin intent := SharedActivity.getIntent; // BecameActive if AAppEvent = TApplicationEvent.BecameActive then begin if Assigned(intent) and TJIntent.JavaClass.ACTION_VIEW.equals(intent.getAction) then begin fileFullPath := JStringToString(intent.getData.getPath); if FileExists(fileFullPath) then begin // обработка файла fileFullPath // ... end; end; end // завершаем Activity при переводе приложения в "Background" else if AAppEvent = TApplicationEvent.EnteredBackground then SharedActivity.finish; // Result := True; end; Хочу обратить внимание, что привел только сам принцип. Очень важно корректно завершить активность (при сворачивании приложения, отключении экрана и т.д. ), т.к. при повторном вызове активности будет вызываться последний из стека. И если его не закрывать будем получить предыдущий, не закрытый activity. А если за приложением зарегистрировано несколько Activity (приложение можно вызвать из ланчера или как в примере, для обработки файла по типу).... в общем тут есть с чем поиграться. Для желающих посмотреть поведение и последовательность выкладываю пример, который формирует лог обработки. Нужно закоментировать: else if AAppEvent = TApplicationEvent.EnteredBackground then SharedActivity.finish; И посмотреть что и когда приложение получает в SharedActivity и AAppEvent. Ссылка в тему: http://developer.android.com/guide/topics/manifest/activity-element.html# Что не получилось: 1) Некоторые программы отдают файл в схеме «content» (к примеру Gmail v5.1 отдает). Как в этом случае получить содержание файла не разобрался. Поэтому в фильтре ограничил вид контента "file" 2) Не смог добраться до стека Activity. Если приложение в памяти и повторно вызывается с новой activity - возможно вот тут это могло пригодиться. (activity ... android:launchMode="singleTop" в этом случае не помог). ADD: было обсуждение, кто как закрывает приложения на андроид, чтобы не оставалось в памяти. Если добавлять SharedActivity.finish приложение 100% убирается из памяти. Intent_Get-File.zip
  22. RoschinSpb

    DisposeOf или Free?

    Согласно учениям великого кормчего Allen Bauer, использование счетчика ссылок это великое достижение мировой цивилизации и гигантский шах человечества на пути ко всеобщему счастью. По этому всегда и везде надо использовать Free или FreeAndNil. Но при этом не забывать про сильные и слабые ссылки. Чаще всего, если какое-то поле класса — экземпляр объекта который создается и разрушается строго внутри этого класса, то это сильная ссылка (по умолчанию), если поле нужно только для хранения ссылки на некоторый внешний экземпляр объекта, то эта слабая ссылка (должна быть директива [weak]). Это нормально работает когда, например объект A хранит ссылку на объект B, но при этом B ни чего не знает про A. type TA = class private [weak] FB: TB; public constructor Create(B: TB); Если не поставите [weak], Вы не сможете удалить объект B до тех пор пока не удалите объект A, либо не обнулите поле FB (а вы его не обнулите, поскольку это приватное поле). Разумеется контроль weak`ов остается на совести программиста. Т.к. формально утечек памяти нет, ссылка-то есть а объекте A, и в момент завершения работы приложения, объект А, и объект B обязательно "честно" удаляться. Просто объект B будет тихохонько сидеть в памяти и ни кого не беспокоить (правда удобно :o) Проблема наступает, если вдруг вам посчастливилось и в объекте B сделать ссылку на объект A. Тогда конечно вы не сможете удалить объект A пока не удалите объект B (см. предыдущий абзац). Обычно всё можно списать всё на "кривость" архитектуры и необходимость исключить перекрестные ссылки. Но вот беда, таких мест, где A ссылается на B, а B ссылается на A очень много, на этом основана вся компонентная архитектура Delphi, на которую ни кто особо не жаловался предыдущие 20 лет. Каждый компонент содержит ссылку на Owner, а Owner содержит список ссылок на все компоненты, которыми владеет. Вот чтобы как-то можно было удалить какой-то компонент придуман метод DisposeOf, он разрушает объект игнорируя все "прелести" счетчика ссылок. Это конечно не эстетично, зато надежно, дешево, практично. Так что вывод такой, что везде, где возможно делаем Free и [weak], а где невозможно DisposeOf.
  23. как в iOS создать превью (Thumbnail) большой картинки и не занять всю память... Тестирую на 11Мб jpg, 14К*9К = 126MPx = 500МБ битмап, взято с запасом против 48Мpx камер Целевое разрешение 120*90 В лоб загрузка и отрисовка превью - дорого по памяти -можно вылететь, особенно в несколько потоков в андроид есть TJBitmapFactory.JavaClass.decodeFile(Options.inSampleSize) и оно в несколько потоков делает превью в иос инет тыкает в CGImageSourceCreateThumbnailAtIndex (kCGImageSourceCreateThumbnailWithTransform и kCGImageSourceThumbnailMaxPixelSize ) из ImageIO заголовков iOSapi.ImageIO - нет, но прикрутил правкой Macapi.ImageIO - поправил фреймворк на libImageIO = '/System/Library/Frameworks/ImageIO.framework/ImageIO'; но не работает, а отладка на теле недоступна т.к. сборка на удаленном маке. код сыпет ImgRef = nil, т.е. CGImageSourceCreateThumbnailAtIndex - не отрабатывает, либо заголовки мною криво накручены либо 126MPx не подъемны для iOS uses iOSapi.CocoaTypes, iOSapi.CoreGraphics, Macapi.CoreFoundation, iOSapi.ImageIO{переделанный Macapi.ImageIO}, Macapi.Helpers, class function TPhotoProxy.LoadInThumb(const Filename:string; Surface:TBitmapSurface; const PrefferedSize:TSize):boolean; var Path: CFStringRef; Url: CFURLRef; ImgSourceRef: CGImageSourceRef; ImgRef: CGImageRef; Dict: CFDictionaryRef; Keys: array [0..10] of Pointer; Value: array [0..10] of Pointer; IntValue: Cardinal; begin Result := False; Path := CFStringCreateWithCString(nil, MarshaledAString(UTF8Encode(Filename)), kCFStringEncodingUTF8); try Url := CFURLCreateWithFileSystemPath(nil, Path, kCFURLPOSIXPathStyle, False); try ImgSourceRef := CGImageSourceCreateWithURL(Url, nil); if ImgSourceRef = nil then raise Exception.Create('ImgSourceRef = nil'); try Keys[0] := CFSTR('kCGImageSourceCreateThumbnailWithTransform'); Value[0] := kCFBooleanTrue; Keys[1] := CFSTR('kCGImageSourceCreateThumbnailFromImageAlways'); Value[1] := kCFBooleanTrue; Keys[2] := CFSTR('kCGImageSourceThumbnailMaxPixelSize'); if PrefferedSize.cx > PrefferedSize.cy then IntValue := Trunc(PrefferedSize.cx) else IntValue := Trunc(PrefferedSize.cy); Value[2] := CFNumberCreate(nil, kCFNumberSInt32Type, @intValue); Dict := CFDictionaryCreate(nil, @Keys[0], @Value[0], 3, nil, nil); try ImgRef := CGImageSourceCreateThumbnailAtIndex(ImgSourceRef, 0, Dict); if ImgRef = nil then raise Exception.Create('ImgRef = nil'); try Result := ImageToSurface(ImgRef, Surface, MaxInt); finally CGImageRelease(ImgRef); end; finally CFRelease(Dict); end; finally CFRelease(ImgSourceRef); end; finally CFRelease(Url); end; finally CFRelease(Path); end; end; к то чем поможет?
  24. На ipad не пробовал. Картинки не сделаны под какойто телефон, изначально они на телефоне лежат с разрешением 1024х768, просто загружаются в битмап он ине loadfromfile, а loatThumbnail, соответственно и памяти кушает в 10 раз меньше. Далее. Есть по-моему огромная разница замостить картинками целый ДБгрид на всем экране или по одной картинке в каждый элемент списка, как минимум разница во столько раз, сколько колонок в ДБГриде. Насчет поедаемой памяти вообще вас не понял. Контрол держит в памяти только столько картинок, сколько итемов видно, а это всегда величина постоянная и небольшая с учетом загрузки миниатюр, а не гигантов реальных размеров. ДБГрид и список - огромная разница в этой реализации ибо у списка в момент скрола если появляется новый элемент в области видимости, то загрузить нужно всего 1 картинку и выгрузить 1, а в гриде много картинок одновременно надо подгружать удалять. Ну и критиковать проще всего. У вас есть решение которое бы позволило иметь огромные списки в тысячу и более элементов с картинками и не вызывало out of memory? Проверю это решение на IPad2, если уж на этом говне будет нормально, то о чем еще говорить... А цели сделать этот список чтобы он хорошо работал у всех бомжей у меня нет, спасибо, хватил уже истории когда всем нужна была поддержка идиотского IE6. Думаю не стоит разработчикам 2 раза на 1 грабли наступать.
  25. размер экрана 2048х1536, сколько памяти уйдет на хранение картинок для базы в 2-3000 записей по 20-30 полей в каждой? пробовал я это делать на дбгриде. но как увидел что памяти жрет сие решение не меряно и при большой количестве записей может вообще выкинуть из-за недостатка оной, особенно на устройствах с 512 памятью, то отказался от этого. слегка подлагивает да и хрен с ним за то памяти не жрет.
×
×
  • Создать...