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

Tarik Live

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

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

  • Посещение

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

  1. Like
    Tarik Live отреагировална Alex7wrt в 9-Patch PNG FMX Generator   
    Сделал небольшую программу-генератор 9-patch заставок. 
    Достаточно выбрать цвет фона, логотип и его видимый размер, и программа сгенерирует 9-patch для всех необходимых  в FMX размеров.

    Примеры
    Рисунок:

    Полученные 9-Patch png:

    Рисунок:

    Полученные 9-Patch png:

     
    Исходники: 9Patch Generator.zip
     
  2. Like
    Tarik Live отреагировална dnekrasov в Таймер в сервисе   
    В архиве - простенький проект. Протестирован на Win и OSX.
     
    TimerThreadDemo.zip
  3. Like
    Tarik Live отреагировална dnekrasov в Таймер в сервисе   
    Когда-то, лет 5 назад у меня возникла такая-же проблема, только в Win32-сервисе. Тогда, для её решения, я написал 2 простеньких класса.
    Вот код, может пригодится?
    unit Utils.TimerThread; interface uses System.Classes, System.SysUtils, System.SyncObjs; type TCustomTimerThread = class abstract (TThread) private FLock: TCriticalSection; FCancelledEvent: TSimpleEvent; FInterval: Integer; FOnTimer: TNotifyEvent; function GetInterval: Integer; function GetOnTimer: TNotifyEvent; procedure SetInterval(const Value: Integer); procedure SetOnTimer(const Value: TNotifyEvent); protected procedure Lock; procedure Unlock; procedure Sleep(AInterval: Integer); reintroduce; procedure TerminatedSet; override; procedure DoOnTimer; virtual; public constructor Create(AInterval: Integer; AOnTimer: TNotifyEvent); reintroduce; procedure BeforeDestruction; override; procedure Cancel; virtual; property Interval: Integer read GetInterval write SetInterval; /// <summary> /// <para> /// За синхронизацией потоков отвечает поток в котором обрабатывается OnTimer /// </para> /// <para> /// !!! НЕ ЗАБЫВАТЬ ПРО ЭТО !!! /// </para> /// </summary> property OnTimer: TNotifyEvent read GetOnTimer write SetOnTimer; end; /// <summary> /// Simple wait thread /// </summary> /// <remarks> /// <para> /// !!! Important !!! /// </para> /// <para> /// Use Cancel instead of Terminate. You can get ThreadExternalTerminate /// exception in multi-thread applications /// </para> /// </remarks> TWaitThread = class(TCustomTimerThread) protected procedure Execute; override; public end; /// <summary> /// Thread independed timer /// </summary> /// <remarks> /// <para> /// !!! Important !!! /// </para> /// <para> /// Use Cancel instead of Terminate. You can get ThreadExternalTerminate /// exception in multi-thread applications /// </para> /// </remarks> TTimerThread = class(TCustomTimerThread) private FEnabled: Boolean; function GetEnabled: Boolean; procedure SetEnabled(const Value: Boolean); protected procedure Execute; override; public constructor Create(AInterval: Integer; AOnTimer: TNotifyEvent; AEnabled: Boolean = True); reintroduce; property Enabled: Boolean read GetEnabled write SetEnabled; end; implementation { TCustomTimerThread } procedure TCustomTimerThread.BeforeDestruction; begin FLock.Free; FreeAndNil(FCancelledEvent); inherited; end; constructor TCustomTimerThread.Create(AInterval: Integer; AOnTimer: TNotifyEvent); begin inherited Create; FInterval := AInterval; FOnTimer := AOnTimer; FreeOnTerminate := True; FLock := TCriticalSection.Create; FCancelledEvent := TSimpleEvent.Create; FCancelledEvent.ResetEvent; end; procedure TCustomTimerThread.Cancel; begin FCancelledEvent.SetEvent; end; procedure TCustomTimerThread.DoOnTimer; begin if Assigned(OnTimer) then OnTimer(Self); end; function TCustomTimerThread.GetInterval: Integer; begin Lock; try Result := FInterval; finally Unlock; end; end; function TCustomTimerThread.GetOnTimer: TNotifyEvent; begin Lock; try Result := FOnTimer; finally Unlock; end; end; procedure TCustomTimerThread.Lock; begin FLock.Enter; end; procedure TCustomTimerThread.SetInterval(const Value: Integer); begin Lock; try FInterval := Value; finally Unlock; end; end; procedure TCustomTimerThread.SetOnTimer(const Value: TNotifyEvent); begin Lock; try FOnTimer := Value; finally Unlock; end; end; procedure TCustomTimerThread.Sleep(AInterval: Integer); begin FCancelledEvent.WaitFor(AInterval); end; procedure TCustomTimerThread.TerminatedSet; begin inherited; FCancelledEvent.SetEvent; end; procedure TCustomTimerThread.Unlock; begin FLock.Leave; end; { TWaitThread } procedure TWaitThread.Execute; begin if FCancelledEvent.WaitFor(FInterval) = wrTimeout then DoOnTimer; end; { TTimerThread } constructor TTimerThread.Create(AInterval: Integer; AOnTimer: TNotifyEvent; AEnabled: Boolean); begin inherited Create(AInterval, AOnTimer); FOnTimer := AOnTimer; FEnabled := AEnabled; end; procedure TTimerThread.Execute; begin while not Terminated do case FCancelledEvent.WaitFor(FInterval) of wrTimeout: begin if Enabled then DoOnTimer; end; else Break; end; end; function TTimerThread.GetEnabled: Boolean; begin Lock; try Result := FEnabled; finally Unlock; end; end; procedure TTimerThread.SetEnabled(const Value: Boolean); begin Lock; try FEnabled := Value; finally Unlock; end; end; end.  
  4. Like
    Tarik Live отреагировална x11 в Toast для Android Service   
    Это не вопрос. Просто подумал, что кому-нибудь может пригодится.
    https://forums.embarcadero.com/thread.jspa?threadID=118465
    Используем 2 файла: Androidapi.JNI.ToastForService.pas + FlyUtils.Android.PostRunnableAndTimer.pas.
    Пример вызова:
    Androidapi.JNI.ToastForService.PostToast('текст сообщения', LongToast); Проверил - работает.
    Есть ещё третий параметр "UseLastToastObj", но я так и не понял, для чего он. Документации нет.
  5. Like
    Tarik Live отреагировална Brovin Yaroslav в Можно ли уменьшить размер приложения для андроида?   
    Если говорить о размере приложения. То первоначально нужно понять, что входить в состав пакета? Затем определить, что нужно и не нужно?
     
    Давайте посмотрим на примере состав пакета небольшого Андроида приложения, написанного в RAD Studio XE5 Delphi. В качестве примера, я взял приложение PhotoEditorDemo, доступный на официальном Open Source проекте примеров RAD Studio XE5
     
    Это пример кроссплатформенного простого фоторедактора:
    Описание примера: http://docwiki.embarcadero.com/CodeExamples/XE5/en/FMX.Mobile.PhotoEditorDemo_Sample_(Delphi) Исходники: http://sourceforge.net/p/radstudiodemos/code/HEAD/tree/branches/RadStudio_XE5_Update/FireMonkeyMobile/Delphi/PhotoEditorDemo/ Размер сжатого приложения
    Собираем приложение и смотрим на результирующий пакет PhotoEditorDemo.apk (Он располагается в директории .\Android\Debug\PhotoEditorDemo\bin относительно корня проекта).
     
    После сборки приложения его размер ~6 760 КБ (в зависимости от Debug or Release сборки). Это размер сжатого пакета нативного приложения.
     
    Размер распакованного приложения
    Если мы распакуем ZIP архиватором этот файл, то увидим его содержание:

    В распакованном виде, пакет занимает 21,7 МБ.
     
    Состав пакета
    Что же входит в его состав:
    lib - место хранения собранных натиных библиотек приложения. Поскольку приложение нативное, то оно работает на основании библиотеки .so. res - место хранения ресурсов приложения (картинки, иконки и тд) META-INF - хранение подписи приложения, контрольные суммы файлов ресурсов (картинок, звуков и т.д.) AndroidManifest.xml - манифест приложения (расширенный аналог VersionInfo в Windows) classes.dex - файл с java реализацией дополнительного функционала FireMonkey. resources.arsc - таблица ресурсов. В этом файле собраны xml-описания всех ресурсов. Самый значительный вклад в размер пакета вносят:
    libPhotoEditorDemo.so (20 060 КБ) - непосредственно сам бинарник приложения classes.dex (1 948 КБ) - частичная реализация FireMonkey на java. Размер самого приложения большой потому, что включает в себя полностью все Delphi библиотеки, которые используется FireMonkey. А это:
    RTL Хедеры для доступа к Android API Нативные стили для Android (три стиля - 1х, 1.5x, 2х, 3х скалирования экрана). Каждый стиль содержит исходную png картинку нативного стиля. Фильтры и эффекты FireMonkey Вся остальная реализация FireMonkey. Довольно большой набор того, что нужно включить в пакет и тяжело выбросить.
     
    Если говорить о приложении написанном в Eclipse, то приложение включает в себя только часть пользовательского кода. И размер мал за счет того, что весь Android API находится перманентно на самом устройстве (не в пакете).
     
    Если бы используемая часть библиотек FireMonkey находилась на каждом устройстве, то размер приложения сократился бы раза в четыре. 
     
    Вывод
    Размер установочного пакета приложения, написанного на FireMonkey не большой для нативных приложений порядка 6 760 КБ для реализации простого фоторедактора (Хотя для кого-то это может быть много). В установленном виде приложение занимает от 20 000 КБ. Основная причина полная интеграция используемых библиотек в пакет приложения. Вероятность уменьшить этот размер маловероятна. Однако увеличение функционала приложения не так сказывается на дальнейший рост приложения.
     
    Можно попробовать сделать усеченные библиотеки, сократить функциональность. Но это не даст ощутимого уменьшения результирующего размера приложения. 
     
    На сколько важен размер приложения для конкретной работы приложения каждый заказчик решает сам.
     
    P.S. Цель этого ответа дать подробный ответ о причинах такого размера, а не попытка вызвать обсуждение на тему сравнения сред разработки. Каждый framework обладает своими достоинствами и недостатками. И выбор средства разработки диктуется совокупностью требования заказчика. 
×
×
  • Создать...