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

Лидеры

  1. Alex7wrt

    Alex7wrt

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


    • Баллы

      6

    • Постов

      508


  2. Евгений Корепов

    Евгений Корепов

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


    • Баллы

      4

    • Постов

      738


  3. dnekrasov

    dnekrasov

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


    • Баллы

      2

    • Постов

      317


  4. sinuke

    sinuke

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


    • Баллы

      1

    • Постов

      190


Популярный контент

Показан контент с высокой репутацией 25.07.2019 во всех областях

  1. Окончательный вариант. Долго бился с изменением размера картинки внутри потока (к примеру что бы в ListView не грузить картинки больше чем нужно). Средствами TBitmap это оказалось сделать невозможно (именно в потоке), чтение форумов, issue Эмбаркадеро, привело к туманному выводу что проблема в архитектуре FMX. В Токио, TBitmap стал потокобезопасным - это означает что никогда не пытайтесь использовать Bitmap в потоке, рано или поздно получите артефакты и глюки. Я решил проблему отказавшись от работы с TBitmap в потоке, и использовав для этого TBitmapSurface (загрузка из stream, изменение размеров). Что умеет хелпер: 1. Загрузка картинки в Bitmap и подгонкой размера (размер можно и не менять - не передавайте параметр ASize) procedure LoadFromURLAsync(const AURL : String; const ASize : TControlSize = nil); overload; 2. Загрузка картинки в TListItemImage ListView. После Окончания загрузки хелпер выполнит AListItemImage.Invalidate в основном потоке приложения для отрисовки картинки. procedure LoadFromURLAsync(const AURL : String; const AListItemImage : TListItemImage); overload; 3. Создание картинки. Тоже самое что и предыдущие, но можно сэкономить строчку кода ABitmap:=TBitmap.Create ? constructor CreateFromUrlAsync(const AURL : String; const AListItemImage : TListItemImage = nil); По картинкам в ListView - можете на свой страх и риск грузить 100500 картинок, но лучше использовать загрузку только для видимой части (+- еще сколько то итемов). Хелпер тупо грузит картинки и не обеспечивает механизм оптимальной загрузки. Протестировано на Windows и Android. Ответы на вопросы которые мне задавали: Почему не создавать отдельный поток для каждой картинки, в нем создавать THTTPClient и делать запрос - пробовал этот вариант, он медленнее на порядок, даже под виндой это чертовски медленно. AHTTPClient.BeginGet и так создает отдельный поток на каждый запрос. Почему AHTTPClient глобальный для юнита - в хелпере нельзя вводить свои переменные, а создавать AHTTPClient внутри функции не выйдет - он убьется до завершения потока. И текущий вариант быстрее. Код хелпера и архив с тестовым проектом: unit BitmapAsyncLoader; interface uses System.Net.HttpClient, System.Net.URLClient, System.SysUtils, System.Types, System.Classes, FMX.Graphics, FMX.Surfaces, FMX.Types, FMX.ListView.Types; type TBitmapAsyncLoader = class helper for TBitmap private function ResizeBitmapSurface(const ABitmapSurface : TBitmapSurface; const AWidth, AHeight : Integer) : TBitmapSurface; procedure SynchronizeAssignFromBitmapSurface(const ABitmapSurface : TBitmapSurface; const AListItemImage : TListItemImage = nil); procedure StartHTTPThread(const AURL : String; const AWidth, AHeight : Integer; const AListItemImage : TListItemImage = nil); public procedure LoadFromURLAsync(const AURL : String; const ASize : TControlSize = nil); overload; procedure LoadFromURLAsync(const AURL : String; const AListItemImage : TListItemImage); overload; constructor CreateFromUrlAsync(const AURL : String; const AListItemImage : TListItemImage = nil); end; implementation type THTTPClientListener = class class procedure HTTPClientValidateServerCertificate(const Sender: TObject; const ARequest: TURLRequest; const Certificate: TCertificate; var Accepted: Boolean); end; var AHTTPClient : THTTPClient; constructor TBitmapAsyncLoader.CreateFromUrlAsync(const AURL : String; const AListItemImage : TListItemImage = nil); begin Create; LoadFromURLAsync(AURL, AListItemImage); end; procedure TBitmapAsyncLoader.LoadFromURLAsync(const AURL : String; const AListItemImage : TListItemImage); var AWidth, AHeight : Integer; begin if Assigned(AListItemImage) then begin AWidth:=Round(AListItemImage.Width); AHeight:=Round(AListItemImage.Height); end else begin AWidth:=-1; AHeight:=-1; end; StartHTTPThread(AURL, AWidth, AHeight, AListItemImage); end; procedure TBitmapAsyncLoader.LoadFromURLAsync(const AURL : String; const ASize : TControlSize = nil); var AWidth, AHeight : Integer; begin if Assigned(ASize) then begin AWidth:=Round(ASize.Width); AHeight:=Round(ASize.Height); end else begin AWidth:=-1; AHeight:=-1; end; StartHTTPThread(AURL, AWidth, AHeight); end; function TBitmapAsyncLoader.ResizeBitmapSurface(const ABitmapSurface : TBitmapSurface; const AWidth, AHeight : Integer) : TBitmapSurface; begin if (AWidth <> -1) and (AHeight <> -1) then begin try Result:=TBitmapSurface.Create; Result.StretchFrom(ABitmapSurface, AWidth, AHeight, ABitmapSurface.PixelFormat); finally ABitmapSurface.Free; end; end else Result:=ABitmapSurface; end; procedure TBitmapAsyncLoader.SynchronizeAssignFromBitmapSurface(const ABitmapSurface : TBitmapSurface; const AListItemImage : TListItemImage = nil); begin TThread.Synchronize(Nil, procedure begin Assign(ABitmapSurface); ABitmapSurface.Free; if Assigned(AListItemImage) then AListItemImage.Invalidate; end ); end; procedure TBitmapAsyncLoader.StartHTTPThread(const AURL : String; const AWidth, AHeight : Integer; const AListItemImage : TListItemImage = nil); begin AHTTPClient.BeginGet( procedure (const ASyncResult: IAsyncResult) var AHTTPResponse : IHTTPResponse; ABitmapSurface : TBitmapSurface; begin if Not ASyncResult.IsCompleted then exit; try AHTTPResponse:=THTTPClient.EndAsyncHTTP(ASyncResult); except exit; end; if Assigned(AHTTPResponse) and (AHTTPResponse.StatusCode = 200) then begin ABitmapSurface:=TBitmapSurface.Create; if TBitmapCodecManager.LoadFromStream(AHTTPResponse.ContentStream, ABitmapSurface, Self.CanvasClass.GetAttribute(TCanvasAttribute.MaxBitmapSize)) then begin ABitmapSurface:=ResizeBitmapSurface(ABitmapSurface, AWidth, AHeight); SynchronizeAssignFromBitmapSurface(ABitmapSurface, AListItemImage); end; end; end, AURL ); end; class procedure THTTPClientListener.HTTPClientValidateServerCertificate(const Sender: TObject; const ARequest: TURLRequest; const Certificate: TCertificate; var Accepted: Boolean); begin Accepted:=True; end; initialization AHTTPClient:=THTTPClient.Create; AHTTPClient.OnValidateServerCertificate:=THTTPClientListener.HTTPClientValidateServerCertificate; finalization if Assigned(AHTTPClient) then AHTTPClient.DisposeOf; end. BitmapAsyncLoader.7z
    4 балла
  2. @Сергей Рыжков , @CyberStorm Почитайте про новое в Delphi 10.3 Rio - статей и видео на эту тему куча.
    2 балла
  3. В справке Google говорится исключительно о targetSdkVersion, а не о minSdkVersion. И targetSdkVersion="26" - это условие для прошлого года. В этом году нужно писать targetSdkVersion="28"
    2 балла
  4. Alex7wrt

    android:minSdkVersion после 1 августа

    Манифест нужно редактировать только в одном месте - в файле AndroidManifest.template.xml, который лежит непосредственно в папке вашего проекта На основе этого файла генерируется файл манифеста, который добавляется к приложению.
    1 балл
  5. Ingalime

    android:minSdkVersion после 1 августа

    Большое спасибо!!! Теперь понятно. P.S. На эмуляторе программа "Hello word!" отработала при 28 версии, а zipalign.exe и aapt.exe = 29
    1 балл
  6. Alex7wrt

    android:minSdkVersion после 1 августа

    Должно работать, но я бы везде использовал 28-ю версию, включая zipalign.exe и aapt.exe.
    1 балл
  7. Alex7wrt

    android:minSdkVersion после 1 августа

    Так как с 1 августа Google требует указывать targetSdkVersion 28 и выше, то логично будет использовать 28-ю версию.29-я это Android 10, который еще не вышел официально. Думаю, проблем с ней не должно быть, но я бы повременил с ее использованием. Обратите внимание, что использование все более новых targetSdkVersion может приводить к некоторым ограничениям, которые вводит Google в новых версиях андроида. Например, при переходе на targetSdkVersion 28 вы обнаружите, что ссылки, начинающиеся на "http" считаются небезопасными и по умолчанию не обрабатываются. Рекомендуется повсеместно переходить на "https". Так что, если вы в каком-нибудь THTTPClient или где-либо еще выполняли запрос на "http", а после перехода на targetSdkVersion 28 обнаружили, что ваш код перестал работать, то либо переходите на "https", либо, если все же необходимо выполнять запрос на "http", внесите изменения в файле манифеста: в разделе application нужно добавить строку android:usesCleartextTraffic="true".
    1 балл
  8. сума сошли это не java
    1 балл
  9. Alex7wrt

    android:minSdkVersion после 1 августа

    Название SDK Version в FMX остается таким каким было при первой установке и не меняется при обновлении Android SDK. Если вы исправно обновляете Android SDK, то в SDK менеджере вы можете указать последние версии ZipAlign Location и Aapt Location, в частности 28.
    1 балл
  10. 1. В Сервисе можно исползовать компонент LocationSensor? 2. Почему мой программа толко один раз получить координату в сервисе а потом не получается? Заранее благодарю за ответ!
    1 балл
  11. sinuke

    переход к x64?

    Вчера утром отправил запрос, вчера же вечером получил ответ(ы):
    1 балл
Эта таблица лидеров рассчитана в Москва/GMT+03:00
×
×
  • Создать...