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

Rusland

Пользователи
  • Постов

    1 204
  • Зарегистрирован

  • Посещение

  • Победитель дней

    26

Активность репутации

  1. Like
    Rusland отреагировална Major в Что лучше: зашивать в ресурсы или Deployment? (Android)   
    я вот сейчас еще раз проверил. Всё, что кидалось в Deployment,  - в apk-файле находится в папке assets. А то, что подключалось через ресурсы (brcc32), то находится в .so-файле.
    Delphi 10.1 Berlin.
    Можете сами проверить
  2. Like
    Rusland отреагировална ENERGY в Странное поведение TThread   
    Еще мультипоточный вариант отсюда: 
     
    class procedure TFireMonkey.CachePictures(const aLV: TListView); begin   Pool.SetMaxWorkerThreads(10); // TThreadPool.Default.MaxWorkerThreads   TParallel.For(0, FMembersList.Count - 1,     procedure(Idx: Integer)     var       AHTTP: TIdHTTP;     begin       if not FileExists(FMembersList[Idx].FileName) then       begin         AHTTP := TIdHTTP.Create(nil);         try           AHTTP.HandleRedirects := true;           FStreamList[Idx].Clear;           AHTTP.Get(FMembersList[Idx].URL, FStreamList[Idx]);         finally           FreeAndNil(AHTTP);         end;         TThread.Queue(TThread.CurrentThread,           procedure           var             AItem: Integer;           begin             if FStreamList[Idx].Size > 0 then             begin               FStreamList[Idx].SaveToFile(FMembersList[Idx].FileName);               AItem := Trunc(Idx / aLV.Columns);               if AItem < aLV.Items.Count then                 aLV.Adapter.ResetView(aLV.Items[AItem]);             end;             Log.d('Current Thread = ' + inttostr(Idx));           end);       end;     end, Pool); end;   
    После загрузки ставьте boolean флаг в своем массиве, обозначающий что картинка загружена. Btw Boolean у Intel и ARM можно записывать и читать без синхронизации между потоками (Т.е. не нужно использовать TMonitor или AtomicExchange ), если он не в packed структуре (packed record).
  3. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в Странное поведение TThread   
    procedure LoadBitmapFromURL(const aURL: string; aBitmap: TBitmap; const aSuccess: TThreadProcedure = nil; const aError: TThreadProcedure = nil); var thread: TThread; begin thread := TThread.CreateAnonymousThread( procedure var HTTP: THTTPClient; Result: TMemoryStream; begin Result := TMemoryStream.Create; HTTP := THTTPClient.Create; try try HTTP.Get(aURL, Result); TThread.Synchronize(TThread.CurrentThread, procedure var aSourceBmp: TBitmap; begin aSourceBmp := TBitmap.Create; try aSourceBmp.LoadFromStream(Result); if not aSourceBmp.IsEmpty then begin aBitmap.SetSize(aSourceBmp.Width, aSourceBmp.Height); aBitmap.CopyFromBitmap(aSourceBmp); if Assigned(aSuccess) then aSuccess; end; finally FreeAndNil(aSourceBmp); end; end); except TThread.Synchronize(TThread.CurrentThread, procedure begin if Assigned(aError) then aError; end); end; finally FreeAndNil(Result); FreeAndNil(HTTP); end; end); thread.FreeOnTerminate := true; thread.start; end; в последнее время пользуюсь такой конструкцией
  4. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в Странное поведение TThread   
    само скачивание картинки HTTPClient.Get должен быть в потоке, а при успешном скачивании нужно делать синхронизацию с главным потоком и "вставлять" картинку в нужное место
  5. Like
    Rusland отреагировална enatechno в Странное поведение TThread   
    Synchronize(LoadImage); Эта строка означает, что LoadImage выполняется в главном потоке (для каждой картинки!).

    Для примера посмотрите эту тему:
     
  6. Like
    Rusland отреагировална AngryOwl в Прозрачные контролы   
    Если не ошибаюсь, то у стандартного стиля для Panel - TRectangle - это и есть весь стиль ))) Потому и не может быть Visible=False )
    Так уберите у него заливку, сделав ее прозрачной. И все.
  7. Like
    Rusland отреагировална enatechno в Прозрачные контролы   
    Полностью согласен. panelstyle - это и есть только один TRectangle. StyleEditor не позволяет его сделать Visible=false. Но можно менять Opacity. Если нужна невидимая панель, то лучше использовать обычный TLayout, который вообще не использует стиль.
    Работа с background в TGroupbox зависит от платформы. Посмотрите в редакторе стилей на дефолтный groupboxstyle:
    - для платформы Windows: текст, используемый для заголовка группы, расположен на объекте background. Если Вы будете менять видимость или прозрачность background, то текст тоже будет невидимым/прозрачным.
    - для платформы Android: текст расположен на отдельном layout. В этом случае изменение видимости/прозрачности background не влияет на отображение текста заголовка.
  8. Like
    Rusland отреагировална AngryOwl в Прозрачные контролы   
    Согласен.
    Я, например, делаю либо свой стиль для нужного компонента, либо делаю копию (например от стиля Android), если хочу чтобы выглядело абсолютно одинаково везде.
    Можно оставить родной стиль для TPanel, сделав свой стиль, типа panelopacitystyle (и потом задав его вашим панелям, которым требуется именно прозрачность), в котором вы можете изголяться со стилем как вашей душе будет угодно. Заполнять панели чем угодно, хоть картинками... При этом, в чем прелесть, - можно программно менять стиль из приложения при необходимости (например, - реакция на какие-либо события).
  9. Like
    Rusland отреагировална enatechno в Прозрачные контролы   
    Это решается редактированием стиля. 
    Например так:
    1). Размещаете TGroupbox на форме
    2). ПКМ на нем
    3). в контекстном меню выбираете Edit Custom Style (или Edit Default style)
    4). в открывшемся редакторе стиля указываете платформу (Android)
    5). выбираете объект background (по умолчанию он белый).
    6). задаете ему свойство Visible=false
  10. Like
    Rusland отреагировална ENERGY в Реестр в Андроиде и Delphi   
    krapotkin
    На мой взгляд формат ini наиболее удобный - Секция > Имя=значение.
    1. Не нашел как делить настройки на секции - в этом основное преимущество ini. 
    2. Парсинг json требует больше времени чем ini. Если настроек много, то это будет в несколько раз медленнее варианта ini. Например в моем проекте кроме основных настроек, есть еще группы, профайлы, и кампании.
    И очень удобно когда секции ссылаются друг на друга, причем втч. читать сам ini файл в текстовом редакторе. 
    К примеру : 
    [Group1]
    Key=Value
    [Profile2]
    Key=Value
    [Campaign1]
    Groups=Group1, Group2
    Profiles=Profile1, Profile2 
    [Campaign2]
    [Campaign3]
     
  11. Like
    Rusland отреагировална krapotkin в Реестр в Андроиде и Delphi   
    это немного вчерашний день
    лучше 
    создавайте в приложении класс настроек и считывайте/записывайте  его одной строкой
  12. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в ColorComboBox произвольный список цветов   
    const aColorNames: array [0 .. 3] of string = ('Black', 'Red', 'Yellow', 'Green'); aColors: array [0 .. 3] of TAlphaColor = (TAlphaColorrec.Black, TAlphaColorrec.red, TAlphaColorrec.Yellow, TAlphaColorrec.Green); procedure TForm1.DoItemApplyStyleLookup(Sender: TObject); var ColorObj: TShape; begin if TListBoxItem(Sender).FindStyleResource<TShape>('color', ColorObj) then ColorObj.Fill.Color := aColors[TListBoxItem(Sender).Tag]; end; procedure TForm1.Button1Click(Sender: TObject); var aItem: TListBoxItem; I: Integer; begin ComboBox1.DropDownKind := TDropDownKind.Custom; // uses FMX.Pickers; for I := Low(aColorNames) to High(aColorNames) do begin aItem := TListBoxItem.Create(ComboBox1); aItem.Parent := ComboBox1; aItem.Text := aColorNames[I]; aItem.Width := aItem.DefaultSize.Width; aItem.Height := aItem.DefaultSize.Height; aItem.StyleLookup := 'colorlistboxitemstyle'; aItem.StylesData['color.Fill.Color'] := aColors[I]; aItem.OnApplyStyleLookup := DoItemApplyStyleLookup; aItem.Tag := I; end; end; как-то так
  13. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в ColorComboBox произвольный список цветов   
    Внутри TComboBox используется TListBox
    Cамый простой способ
    кинуть на форму TListBox ПКМ Add TListBoxItem выбрать нужный стиль для Item (StyleLookup) ПКМ по Item Edit Custom Style меняем что нужно в стиле и сохраняем применяем новый стиль к Item
  14. Like
    Rusland отреагировална Brovin Yaroslav в Описание TfgRatingBar   
    Доработал компонент. Добавлено:
    Поддержка Tint эффекта - TfgRatingBar.TintColor Автоматический размер - TfgRatingBar.AutoSize Режим только отображения - TfgRatingBar.ReadOnly Событие окончательного изменения рейтинга (отжатие пальца от экрана или кнопки мышки) - TfgRatingBar.OnChange Событие в процессе изменения рейтинга - TfgRatingBar.OnChanging

  15. Like
    Rusland отреагировална Brovin Yaroslav в [Статья] Жизненный цикл объектов в Delphi. Часть 2. Android, iOS. Что же использовать Destroy, Free, FreeAndNil или DisposeOf?   
    Ссылка: http://yaroslavbrovin.ru/object_life_cycle_in_delphi_part_2_android_ios-ru/ Автор: Ярослав Бровин Продолжаем тему жизненного цикла объектов в мире Delphi, но в этой части рассматриваем эту тему в рамках мобильных платформ Android и iOS.
    Delphi вводит новый подход к управлению памятью в мобильных платформах. Появляется автоматический подсчет ссылок, который с одной стороны облегчает код разработчика и должен помочь ему, а с другой стороны раскладывает равномерно грабли на пути освоения новых платформ в мире Delphi.
  16. Like
    Rusland отреагировална SerhioUser в Как получить версию APK-файла под Win32?   
    Благодарю, Евгений Корепов!
    Вот функция GetApkVersion() на C++ для получения версии APK-файла, и слегка подкорректированная вышеописанная функция запуска:
    String __fastcall ShellExecutePipe(String CommandLine, String AWorkDir = "C:\\", UINT Flag = SW_HIDE) { TSecurityAttributes SA; TStartupInfo SI; TProcessInformation PI; HANDLE StdOutPipeRead, StdOutPipeWrite; bool WasOK; char Buffer[256]; unsigned long BytesRead; String WorkDir; bool Handle; String AOutputLine; String Result; SA.nLength = sizeof(SA); SA.bInheritHandle = true; SA.lpSecurityDescriptor = NULL; CreatePipe(&StdOutPipeRead, &StdOutPipeWrite, &SA, 0); try { setmem(&SI, sizeof(SI), 0); SI.cb = sizeof(SI); SI.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; SI.wShowWindow = Flag; SI.hStdInput = (unsigned)GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin SI.hStdOutput = (unsigned int)StdOutPipeWrite; SI.hStdError = (unsigned int)StdOutPipeWrite; WorkDir = AWorkDir; Handle = CreateProcess(NULL, CommandLine.c_str(), NULL, NULL, true, 0, NULL, WorkDir.c_str(), (STARTUPINFO*)&SI, &PI); } catch(Exception &e) { } CloseHandle(StdOutPipeWrite); if (Handle) { try { do { WasOK = ReadFile(StdOutPipeRead, Buffer, 50, &BytesRead, NULL); if(BytesRead > 0) { Buffer[BytesRead] = 0; AOutputLine = Buffer; Result = Result + AOutputLine; } }while(WasOK && (BytesRead != 0)); WaitForSingleObject(PI.hProcess, INFINITE); } __finally { CloseHandle(PI.hThread); CloseHandle(PI.hProcess); } } CloseHandle(StdOutPipeRead); return Result; } //--------------------------------------------------------------------------- String __fastcall GetShortName(String sLongName) { String ret; String sShortName; int nShortNameLen; sShortName.SetLength(MAX_PATH); nShortNameLen = GetShortPathName( sLongName.c_str(), sShortName.c_str(), MAX_PATH - 1); if (nShortNameLen != 0) { sShortName.SetLength(nShortNameLen); ret = sShortName; } return ret; } //--------------------------------------------------------------------------- String __fastcall GetApkVersion(String FileName) { String ret; String AppPath = GetShortName(ExtractFileDir(Application->ExeName)); FileName = GetShortName(FileName); if(FileName != "") { String cmd = (String)"cmd /c \""+ AppPath + "\\aapt.exe\"" + " dump badging " + FileName; String res = ShellExecutePipe(cmd, AppPath); TStringList *sl = new TStringList; sl->Delimiter = ' '; sl->DelimitedText = res; ret = AnsiDequotedStr(sl->Values["versionName"], '\''); if(ret != "") ret += "."; ret += AnsiDequotedStr(sl->Values["versionCode"], '\''); delete sl; } return ret; } //--------------------------------------------------------------------------- Всем спасибо за участие.
  17. Like
    Rusland отреагировална ENERGY в Реестр в Андроиде и Delphi   
    SharedPreference удаляются при деинсталяции программы. 
  18. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в Как заполнить эллипс?   
    var MyRect: TRectF; begin MyRect := RectF(10, 10, 30, 30); if Canvas.BeginScene then try Canvas.Fill.Color := TAlphaColorRec.Red; Canvas.Stroke.Color := TAlphaColorRec.Black; Canvas.FillEllipse(MyRect, 1); Canvas.DrawEllipse(MyRect, 1); finally Canvas.EndScene; end; end; FillEllipse - заливка
    DrawEllipse - обводка
  19. Like
    Rusland отреагировална dante333 в Как убрать лишние уведомления в шторке при пуше?   
    Kitty,а вы попробуйте переустановить свое приложение.Удалить и заново поставить.Получите +1 к пушам. Было 3,станет 4.Больше переустановок,больше пушей. Когда работал с Kinvey была такая же история.В блогах на Embarcadero обсуждали даже.Если в кратце и по памяти,то при переустановке приложения,в Kinvey дублируется запись устройства на которое отправляется push.Что бы избежать этого,надо делать доп проверку на уже существующий токен для данного устройства.Повторюсь что это по памяти,но суть понятна.Можете поискать в блогах Sarina Dupont на Embarcadero.
    Собственно после этого я и перешел на нативные пуши. Потому как написал многоуважаемый ZuBy:
    Вот,нашел:
    https://community.embarcadero.com/blogs/entry/remote-push-notifications-on-android-with-rad-studio-xe6-795
    Второй коммент.
    15 раз установил,15 пушей.
  20. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в Принудительная остановка прокрутки ListView   
    На мобильных это делается с помощью TAniCalculations, в ModernLV есть метод getAniCalc
    if ListView1.getAniCalc <> nil then ListView1.getAniCalc.Animation := false; в момент вызова этого кода скроллинг остановится
  21. Like
    Rusland отреагировална Равиль Зарипов (ZuBy) в Рисование маршрута на MapView, Delphi, Android   
    Вас не смущает что это локальная переменная?
  22. Like
    Rusland отреагировална kami в [ANDROID] Создание и удаление компонентов run-time   
    Поправка: это самый верный способ для FMX, вне зависимости от платформы.
    Емнип, у TCircle нет наследников. Ну и - для использования Release не обязательно приводить тип к истинному классу объекта.
    Поэтому сей код можно записать так (не проверял в IDE, но если скомпилируется - значит всё нормально):
    for k:=Layout1.ChildrenCount-1 downto 0 do if Layout1.Children[k] is TCircle then Layout1.Children[k].Release;  
  23. Like
    Rusland отреагировална ENERGY в Утечка при использовании анонимного метода или анонимные методы, циклические ссылки и ARC   
    Это касается ARC компиляторов, Android, iOS и будущего Linux.
    Если контейнер владелец, содержит классы, которые используют анонимный метод для общения с ним (классом владельцем), то такая конструкция порождает утечку памяти из-за появления циклической ссылки. Т.к. при присваивании анонимного метода инкрементируется счетчик ссылок и не меняется. Причем это не указано в хелпе.

    А дело было так - при вызове MyCore.Free класс не уничтожался - не вызывался деструктор из за того, что после вызова Free, счетчик ссылок (reference Count) был равен 1. Приходилось пользоваться  DisposeOf. Решил разобраться.
    Для этого перекрыл виртуальные методы TObject отвечающие за изменения счетчика объекта (см. также полный пример ниже).
    function __ObjAddRef: Integer; override;
    function __ObjRelease: Integer; override;
     
    Итак TCore содержит класс TTestClass - у которого есть событие OnMyEvent. 
    Прототип описан как анонимная процедура - TAnonymProc = reference to procedure;

    При указании анонимной процедуры, т.е. : 
    procedure TCore.SetEvent; begin   fTest.OnMyEvent := procedure ()   begin     fSetFlag := true;   end; end; счетчик ссылок TCore увеличивается на 1 и не изменяется при выходе из SetEvent.
    Теперь при вызове Free TCore - не будет вызван деструктор, который должен уничтожит классы TCore и TTestClass и произойдет утечка памяти.

    Решение : 
    1. Использовать слабые ссылки - weak, в нашем примере добавить атрибут [weak]:
    TTestClass = class strict private   [weak]fOnMyEvent:TAnonymProc; public   property OnMyEvent: TAnonymProc read fOnMyEvent write fOnMyEvent; end;  При присваивании объекта в переменную со слабой ссылкой не происходит увеличение счётчика ссылок объекта на единицу. Аналогично, при очистке слабой ссылки не происходит уменьшение счётчика объекта на единицу.
    2. Не использовать анонимные методы, а использовать обычные указатели на метод: 
    Вместо TAnonymProc = reference to procedure; используем классический 
           TAnonymProc = procedure of object;

    Демо пример, где можно отследить утечку прикрепил.
    Полный код: 
     
    AnonMethodsCycle.zip
  24. Like
    Rusland отреагировална AliZairov в Update 2 + iOS 10.2   
    Привет. Hotfix PAServer XCode 8.2 30680
  25. Like
    Rusland отреагировална enatechno в Запуск компилированного приложения.   
    Создал 2 тестовых проекта (один VCL, другой FMX). В обоих только форма с кнопкой.
    Компилировал из 10 Seattle и 10 Berlin (конфигурация Debug).
    Запускал на win 7 и 10.
    Задержки в 1-2 сек не наблюдал. На глаз оба проекта запускаются с одинаковой скоростью.
    Конфигурация компьютера аналогична Вашей.
    https://www.youtube.com/watch?v=5q8ZKiYEWko
×
×
  • Создать...