Лидеры
Популярный контент
Показан контент с высокой репутацией 14.08.2015 во всех областях
-
[Android] программа закрывается при использовании LocationSensor и Memo
zairkz и 3 других отреагировал Brovin Yaroslav за вопрос
Если у вас зависает программа, то замените Synchronize на TThread.Queue. Это точно должно помочь Этим летом мне выделили время и я плотно занимался проблемой "черного экрана" на андроиде и креша при закрытии приложения на Андроиде. На форуме было очень много обсуждений этой проблемы. Поэтому есть пара советов, как ее избежать в текущих версия среды: Все операции требуемые выполнять в Delphi UI потоке нужно выполнять в Synchronize или Queue. Второе предпочтительнее. Отличие между Synchronize и Queue - только в том, что первое остановит выполнение потока до тех пор, пока не выполниться код в Synchronize. Queue наборот, поставить в очередь ваш код на выполнение. Поэтому если вы можете выполнять вашу задачу асинхронно, то лучше использовать Queue, если нет, то Synchronize. В вашем случае вы можете выполнить добавление маркера асинхронно, так как результат сенсора вы не используете в будущем для вычислений. То есть у вас только задача отображения данных в Real Time. Поэтому4 балла -
Все "быстренько" бывает только если приложение простое "как две копейки"... В реальности - это действительно напрягает. Извернуться можно примерно так: - создайте форму (например fmSplash) и на ее событие OnFormCreate делаете все что вам нужно - создайте TfgProgressDialog (например), который будет отображать процесс загрузки приложения и инициализацию переменных, модулей и т.п. - подготовьте все что вам нужно для вашего приложения, до создания главной формы (и других) - все что требует отображения в TfgProgressDialog помещайте в блоки TThread.Synchronize(TThread.CurrentThread, procedure begin {....} end); - все что не требует отображения в GUI и никак не связано с компонентами других форм, и что может выполняться "постольку-поскольку" помещайте в блоки TThread.CreateAnonymousThread(procedure begin {...} end).Start; - и когда, на ваш взгляд, уже пора создать главную форму приложения - обновите информацию в TfgProgressDialog и в блоке TThread.Synchronize(TThread.CurrentThread, procedure begin {....} end); создайте все формы вашего приложения... З.Ы. как пример можете посмотреть тут. просто иначе объяснить не вижу возможности...2 балла
-
[Android] программа закрывается при использовании LocationSensor и Memo
zairkz отреагировал Равиль Зарипов (ZuBy) за вопрос
Это все конечно хорошо, но не всегда работает. Вот такая зверская конструкция на Windows отрабатывается на ура, а на андроиде бывают лаги TTask.Run(procedure begin // тут обращение к базе например TThread.Synchronize(nil, procedure begin // тут разбираем данные TTask.Run(procedure begin // тут сохраняем TThread.Queue(nil, procedure begin // тут обновляем данные в визуальных компонентах end); end); end); end); пришлось отказаться от такой конструкции, но иногда она жутко удобна1 балл -
Подскажите, как транслировать изображение экрана Андроид-смартфона на ПК? Желательно без root и для версии 4.1.1 4.21 балл
-
"- создайте форму (например fmSplash) и на ее событие OnFormCreate делаете все что вам нужно - и когда, на ваш взгляд, уже пора создать главную форму приложения - обновите информацию в TfgProgressDialog и в блоке TThread.Synchronize(TThread.CurrentThread, procedure begin {....} Application.CreateForm(TfmMain, fmMain); end); создайте все формы вашего приложения..." чего там только нет... даже боюсь начать перечислять...1 балл
-
[TImage] Как сделать увеличение\уменьшение TImage при помощи двух пальцев?
Brovin Yaroslav отреагировал enatechno за вопрос
Есть в примерах. Samples\Object Pascal\Mobile Snippets\InteractiveGestures\ImageZoom\ImageZoom.dproj или тут1 балл -
если мы говорим про XE8 дебаг работает, просто нужно правда глючный он нынче очень теперь он почти не показывает поля объектов, в потоках вообще беспомощен хорошо помогает присваивание во временные локальные переменные простых типов. их он видит нормально1 балл
-
Оптимизация
zairkz отреагировал FeLDMARShaL за вопрос
Долго думал над тем в какую ветку форума запихать свой вопрос, возможно по этой причине не смог найти ответа. Меня интересуют вопросы оптимизация приложения. Причем во всех смыслах. Во-первых, хочется максимально разогнать работу интерфейса, время отклика от нажатия на контролы уменьшить бы, или к примеру, сделать более плавное прокручивание на сролпанели. Единственное что нашел своими силами в этом направлении, это свойство у формы Quality. Это свойство я выставил в HighPerfomance. (кстати, а я правильно понял, что это то что мне надо?). После выставления этого свойства, я визуально заметил, что стало более быстро все работать. Но больше ничего не смог придумать. К примеру, на iOS устройстве, панель (скроллируемая) на которой находятся кнопки (много кнопок) заметно тормозит при сроле – т.е. сразу палится что это не нативное приложение. А также замечаю, что самое первое нажатие на кнопку, тоже подвисает, по отношению ко второму нажатию. Во-вторых, я заметил, что приложение, которое свернули в фоновом режиме очень сильно кушает аккумулятор. К примеру, на моем андройде, за 12 часов аккумулятор со 100% сел до 60%. На iPhone со 100% до 85%. Это при учете что wi-fi был отключен, и без симкарты телефоны были. Т.е. без приложения максимум просадка за 12 часов это 1-2%. К счастью, пока радует, что стандартная андройдовская фитча не показывает, что это именно наше приложение кушает аккумулятор – но думаю, что опытные пользователи раскурят в чем причина того что девайс, стал сильно проседать по заряду. Само собой, когда приложение в фоне оно не работает, никаких потоков там не запускается и ничего не делается. Я думаю может какой-то датчик включился или еще что-нибудь. В общем нужен совет как можно уменьшить потребление заряда аккумулятора. В общем нужны любые советы (можно из реальной жизни) или какие-нибудь мануалы как разогнать приложение и сократить ресурсопотребляемость его. П.С, совсем скоро будем заливать наше приложение в AppStore и GooglePlay, и хочется, чтобы оно вело себя максимально нативно (похоже на приложения, написанные специально под эти плтформы) Буду благодарен любым ссылкам, мастер-классам, примерам кода, мануалам, документации, может быть какие-нибудь конференции по этому поводу или веб семинарам…1 балл -
[Android] программа закрывается при использовании LocationSensor и Memo
Rusland отреагировал Равиль Зарипов (ZuBy) за вопрос
с какими точно не могу сказать, это зависит от того какие компоненты вы используете. например карта (судя по коду) тоже работают в отдельном потоке, но пока проблем не было ограничения по Memo я поставил 1000 символом и после чего очищаю его (для логов использовал)1 балл -
Недостающий вариант Image WrapMode
Brovin Yaroslav отреагировал krapotkin за вопрос
Большое спасибо за готовое решение. Я примерно то же делал ручками через копирование по месту. Конечно, было бы круто, чтобы эта функциональность попала в стандартный image. Там ведь есть всякие варианты типа TRectangle.Fill, в которые тоже можно пихать картинки...1 балл -
Особо править нет времени, разберетесь. Все просто - это компонент, унаследованный от стандартного TImage, с теми свойствами, которые Вам нужны. unit Sphere.ImageEx; interface uses System.Classes, System.Types, FMX.Types, FMX.Objects, FMX.Graphics; type TBitmapFit = (bfDefault, bfWidth, bfHeight, bfBoth); TImageEx = class(TImage) private FBitmapDisplayRect: TRectF; procedure SetBitmapFit(const Value: TBitmapFit); protected FBitmapFit: TBitmapFit; procedure Paint; override; public constructor Create(AOwner: TComponent); override; function ImagePointToBitmap(const APoint: TPointF): TPointF; property BitmapDisplayRect: TRectF read FBitmapDisplayRect; published property BitmapFit: TBitmapFit read FBitmapFit write SetBitmapFit; end; implementation { TImageEx } constructor TImageEx.Create(AOwner: TComponent); begin inherited; FBitmapFit := bfDefault; FBitmapDisplayRect := TRectF.Empty; end; function TImageEx.ImagePointToBitmap(const APoint: TPointF): TPointF; begin Result := APoint; if not (BitmapDisplayRect.IsEmpty) and Assigned(Bitmap) then begin Result.X := Result.X - Trunc(BitmapDisplayRect.Left); if Bitmap.Width > BitmapDisplayRect.Width then Result.X := Result.X / (BitmapDisplayRect.Width / Bitmap.Width ); Result.Y := Result.Y - Trunc(BitmapDisplayRect.Top); if Bitmap.Height > BitmapDisplayRect.Height then Result.Y := Result.Y / (BitmapDisplayRect.Height / Bitmap.Height ); end; end; procedure TImageEx.Paint; begin {весь код - в прикрепленном файлике} // всегда центрируем для этих методов отрисовки else if FBitmapFit <> bfDefault then begin // растягиваем по ширине с обрезкой верхнего/нижнего краев Canvas.BeginScene(); try Coef := B.Width / B.Height; R := RectF(0, 0, B.Width, B.Height); if FBitmapFit = bfWidth then R := RectF(0, 0, Width, Width / Coef) else if FBitmapFit = bfHeight then R := RectF(0, 0, Height * Coef, Height) else if FBitmapFit = bfBoth then begin if Coef >= 1 then R := RectF(0, 0, Height * Coef, Height) else R := RectF(0, 0, Width, Width / Coef); end; RectCenter(R, LocalRect); Canvas.DrawBitmap(B, RectF(0, 0, B.Width, B.Height), R, AbsoluteOpacity, DisableInterpolation); FBitmapDisplayRect := R; finally Canvas.EndScene(); end; end; end; procedure TImageEx.SetBitmapFit(const Value: TBitmapFit); begin if FBitmapFit <> Value then begin FBitmapFit := Value; Paint(); end; end; //initialization // RegisterFMXClasses([TImageEx]); end. Sphere.ImageEx.zip1 балл
-
[TImage] Как сделать увеличение\уменьшение TImage при помощи двух пальцев?
Brovin Yaroslav отреагировал Alex7wrt за вопрос
Здесь можно почитать про обработку мультитача в Delphi XE71 балл -
procedure TMainForm.SearchChanelEditChangeTracking(Sender: TObject); var Lower: string; begin Lower := SearchChanelEdit.Text.Trim.ToLower; if Lower = '' then begin if Assigned(listView.Items.Filter) then begin // Clear filter listView.Items.Filter := nil; end; end else begin // Start or update filter listView.ItemIndex := -1; listView.Items.Filter := function(X: string): Boolean begin Result := Lower.IsEmpty or X.ToLower.Contains(Lower); end; end; end; Передача фильтра в ListView1 балл
-
узнать расстояние между 2 точками
Евгений Корепов отреагировал Равиль Зарипов (ZuBy) за вопрос
uses Math, FMX.Maps function TMapsEngine.GetDistance(const aStart, aEnd: TMapCoordinate): Real; const Radius = 6372795; PiDiv180 = Pi / 180; var CosLatStart, SinLatStart, CosLatEnd, SinLatEnd, Delta, CosDelta, SinDelta, X, Y: Real; begin try CosLatStart := Cos(aStart.Latitude * PiDiv180); CosLatEnd := Cos(aEnd.Latitude * PiDiv180); SinLatStart := Sin(aStart.Latitude * PiDiv180); SinLatEnd := Sin(aEnd.Latitude * PiDiv180); Delta := (aEnd.Longitude * PiDiv180) - (aStart.Longitude * PiDiv180); CosDelta := Cos(Delta); SinDelta := Sin(Delta); Y := Sqrt(((CosLatEnd * SinDelta) * (CosLatEnd * SinDelta)) + ((CosLatStart * SinLatEnd - SinLatStart * CosLatEnd * CosDelta) * (CosLatStart * SinLatEnd - SinLatStart * CosLatEnd * CosDelta))); X := SinLatStart * SinLatEnd + CosLatStart * CosLatEnd * CosDelta; Result := Round(ArcTan2(Y, X) * Radius); except Result := -1; end; end; рассчитывает отрезок по прямой, не по дороге!1 балл -
Google Maps или альтернатива.
Rusland отреагировал Brovin Yaroslav за вопрос
В XE8 добавлен новый компонент TMapView, который позволяет отобразить карту в вашем приложении и не только. Поддерживаемые платформы: Android и iOS. Руководство использования Конфигурация андроид приложения для работы с Google Maps1 балл -
[Андроид] Можно ли эмулировать координаты GPS на эмуляторе?
Rusland отреагировал Brovin Yaroslav за вопрос
Добрый день, Стандартный эмулятор поддерживает указание гео координат. Но для этого нужно подключиться к симулятору через telnet и прописать ему ручками местоположение. 1. Включаем поддержку клиента Telnet для Windows 7-8 Пуск - Панель управления - Программы и компоненты - Включение или отключение компонентов windows - Клиент Telnet (ставим галочку) 2. Подключаем к эмулятору через telnet Запускаем командную строку cmd: 3. Задаем координаты эмулятора задаем координаты и смотрим, как в сенсоре срабатывает событие смены геопозиции: Подробности тут: Using the Emulator Console Geo Location Provider Emulation1 балл -
Не за что. Если что спрашивай. XML формат мне всегда был противен, хоть и понятен, но все равно внутренне я был против него и как следствие принципиально не использовал в своих программах. Но вот формат JSON мне очень понравился. Его легко написать от руки, легко читать, даже через регулярки парситься легко, если приспичило. И он не избыточен как XML, а значит по канала связи передается меньше трафика. Так что не бросай этот формат И кстати, что касается утечек. Я когда сам только начинал разбираться в формате JSON и с тем как работать с ним в Delphi, у меня тоже были утечки, ибо я использовал JSON для парсинга ответа с сервера, в потоке. Я тогда начал склоняться к всеобщему мнению что просто сама реализация работы с этим форматом в делфи кривая. Но поколебавшись все таки принял во внимание ту мысль, что разработчики Embacadero на девять жизней умнее меня, и вряд ли они выпустили модуль с таким явным глюком. И решил все таки углубиться дальше. Как оказалось просто поставить JS.Free в конце не достаточно. Т.е. вот так вот делать не стоит: var JS: TJSONObject; begin s := '{"jsonString":"ok"}; JS := TJSONObject.ParseJSONValue(s) as TJSONObject; ShowMessage(JS.GetValue('jsonString').Value); JS.Free; end; В процессе работы потока с ним может случиться все что угодно - обрыв связи, тайоут сработает, или некорректные данные, или еще что нибудь. И JS объект может не освободиться. Т.е. поток может уже и не существует, но в оперативке созданный объект лежит. К тому же при таком подходе могут быть и ошибки, например параметра 'jsonString' может и не быть, и все вывалиться в ошибку (но в потоке этого можно и не увидеть) и до JS.Free код никогда не дойдет. А значит будет опять утечка памяти. Так что правильней всего делать через Assigned: var JS: TJSONObject; begin s := '{"jsonString":"ok"}'; JS := TJSONObject.ParseJSONValue(s) as TJSONObject; if Assigned(JS) then begin ShowMessage(JS.GetValue('jsonString').Value); JS.Free; end; end; Тогда утечек не будет. Это я теперь точно знаю!)))1 балл