• 0
Alex7wrt

Удаление сложных классов, Android

Вопросы

Добрый день.
Знаю, что на форуме есть несколько тем о том, как удалять объекты под Android и счетчике ссылок, однако использование рекомендаций оттуда мне пока не помогло.
Суть вопроса: создаю свой класс

 

type
    TRext =class(TRectangle)
        Text: TText;
        procedure RextMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
        procedure RextMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
        procedure RextMouseLeave(Sender: TObject);
        Constructor Create(AOwner: TComponent); override;
        Destructor Destroy; override;
end; 

type
TMyChoose = class
        Item1, Item2, Item3: TRext; 
        Edits: TEdit;
        procedure ItemClick(Sender: TObject);
        procedure OnEditFocus(Sender: TObject; var ACanFocus: Boolean);
        Constructor Create(Form: TForm);
        Destructor Destroy; override;
end;
.....
constructor TRext.Create(AOwner: TComponent);
begin
    inherited Create(AOwner);
    Text:=TText.Create(Self);
    Text.Parent:=Self;
    Text.Align:=TAlignLayOut.Client;
    Self.Text.OnMouseDown:=RextMouseDown;
    Self.Text.OnMouseUp:=RextMouseUp;
    Self.Text.OnMouseLeave:=RextMouseLeave;
end;

Destructor TRext.Destroy;
begin
    Text.Release; Text:=nil;
    inherited;
end;

constructor TMyChoose.Create(Form: TForm);
begin
    inherited Create;
    Item1:=TRextCreate(Form);
    Item1.Parent:=Form;
    Item1.Align:=tAlignLayout.MostLeft;    
    Item2:=TRextCreate(Form);
    Item2.Parent:=Form;
    Item2.Align:=tAlignLayout.MostLeft;
    Item3:=TRextCreate(Form);
    Item3.Parent:=Form;
    Item3.Align:=tAlignLayout.MostLeft;
    Edits:=TEdit.Create(Form);
    Edits.Parent:=Form;
    Edits.Align:=tAlignLayout.MostLeft;
    .........
end;

Destructor TMyChoose.Destroy;
begin
    Item1.Release; Item1:=nil;
    Item2.Release; Item2:=nil;
    Item3.Release; Item3:=nil;
    Edits.Release; Edits:=nil;
    inherited;
end;

Под Windows все нормально работает и уничтожается. Под Android вызов Destroy у объекта типа TMyChoose не приводит ни к чему.
Вместо Release и nil использовал также DisposeOf и Nil, а также FreeAndNil - результат аналогичный.
Как правильно уничтожать составные объекты?

Изменено пользователем Alex7wrt

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 ответов на этот вопрос

  • 0

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Столкнулся с такой же проблемой. Удалось ли решить вопрос?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Напишу более развернуто.

Есть класс

type
  TEssence = class(TRectangle)
  private
    procedure EssenceMouseEnter(Sender: TObject);
    procedure EssenceMouseLeave(Sender: TObject);
  public
    EssenceName: TLabel;
    EssenceImage: TImage;
    constructor Create(AOwner: TComponent); Override;
    destructor Destroy; Override;
    procedure SetName(Name: string);
    procedure SetIcon(iconnumber: integer);

  end;

constructor TEssence.Create(AOwner: TComponent);
var
  Size: TSizeF;
begin
  // if Form1.MasterLayout.FindComponent('RoomsScrollBox') <> nil then
  // begin
  inherited Create(AOwner);
  // Parent := Form1.MasterLayout.FindComponent('RoomsScrollBox') as tvertscrollbox;
  Parent := Form1.RoomsScrollBox;
  XRadius := Form1.SkinSettings.Radius;
  YRadius := Form1.SkinSettings.Radius;
  Stroke.Thickness := Form1.SkinSettings.StrokeTikness;
  Stroke.Color := Form1.SkinSettings.StrokeColor;
  Fill.Color := Form1.SkinSettings.FillColor;
  Margins.Top := 5;
  Margins.Bottom := 5;
  Margins.Left := 10;
  Margins.Right := 10;
  Align := TAlignLayout.Top;
  Position.Y := 1000;
  Height := Form1.SkinSettings.Height;
  OnMouseEnter := self.EssenceMouseEnter;
  OnMouseLeave := self.EssenceMouseLeave;

  EssenceImage := TImage.Create(self);
  EssenceImage.Parent := self;
  EssenceImage.Align := TAlignLayout.Left;
  Size.cx := Form1.SkinSettings.ImageWidth;
  Size.cy := Form1.SkinSettings.ImageWidth;
  EssenceImage.Width := Form1.SkinSettings.ImageWidth + 2;
  EssenceImage.Margins.Left := 5;
  EssenceImage.Margins.Right := 0;
  EssenceImage.WrapMode := TImageWrapMode.Fit;
  EssenceImage.MarginWrapMode := TImageWrapMode.Original;
  EssenceImage.Locked := true;
  EssenceImage.HitTest := false;

  EssenceImage.Bitmap := Form1.ImageList1.Bitmap(Size, 1);

  EssenceName := TLabel.Create(self);
  EssenceName.Parent := self;
  EssenceName.Margins.Top := 5;
  EssenceName.Margins.Bottom := 5;
  EssenceName.Margins.Left := 5;
  EssenceName.Margins.Right := 10;
  EssenceName.Align := TAlignLayout.Client;
  EssenceName.StyledSettings := [TStyledSetting.Family];
  EssenceName.Font.Size := Form1.SkinSettings.FontSize;
  EssenceName.FontColor := Form1.SkinSettings.FontColor;
  EssenceName.Font.Style := EssenceName.Font.Style + Form1.SkinSettings.FontStyle;
  EssenceName.Text := 'Тест';
  EssenceName.WordWrap := false;
  EssenceName.Locked := true;
  EssenceImage.HitTest := false;
  // end;
end;

destructor TEssence.Destroy;
var
  i: integer;
begin
  EssenceImage.disposeof;
  EssenceName.disposeof;
  //EssenceImage.Parent := nil;
  //EssenceImage.Free;
  //EssenceName.Parent := nil;
  //EssenceName.Free;
  inherited;
end;

на базе него есть другой класс

type
  TRele = class(TEssence)
  public
    Device_ID: byte;
    Device_Adress: byte;
    // ReleImage: TImage;
    // ReleName: TLabel;
    ReleSwitch: TSwitch;
    ReleTimer: TTimer;
    constructor Create(AOwner: TComponent); Override;
    destructor Destroy; Override;
    procedure ReleSwitchClick(Sender: TObject);
    procedure ReleOnTimer(Sender: TObject);
  end;

constructor TRele.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ReleSwitch := TSwitch.Create(self);
  ReleSwitch.Parent := self;
  ReleSwitch.Align := TAlignLayout.Right;
  ReleSwitch.Margins.Top := 15;
  ReleSwitch.Margins.Bottom := 15;
  ReleSwitch.Margins.Left := 0;
  ReleSwitch.Margins.Right := 10;
  ReleSwitch.Width := 55;
  ReleSwitch.IsChecked := false;
  ReleSwitch.Locked := true;
  ReleSwitch.HitTest := false;

  self.OnClick := self.ReleSwitchClick;

  ReleTimer := TTimer.Create(self);
  ReleTimer.Parent := self;
  ReleTimer.Interval := 1000;
  ReleTimer.OnTimer := self.ReleOnTimer;
  ReleTimer.Enabled := true;

end;

destructor TRele.Destroy;
begin
  ReleSwitch.Parent := nil;
  ReleSwitch.Free;
  ReleSwitch:=nil;
  ReleTimer.Parent := nil;
  ReleTimer.Free;
  ReleTimer:=nil;
  inherited;
end;

создаю экземпляры класса trele.

rele := TRele.Create(Form1.RoomsScrollBox);

 

при нажатии на экземпляр класса должно произойти полное удаление всех элементов на Form1.RoomsScrollBox

for i := Form1.RoomsScrollBox.ComponentCount - 1 downto 0 do
  begin
    if Form1.RoomsScrollBox.Components[i] is TScrollContent then
    begin
      application.ProcessMessages;
    end
    else if Form1.RoomsScrollBox.Components[i] is TEssence then
    begin
      (Form1.RoomsScrollBox.Components[i] as TEssence).Parent:=nil;
      (Form1.RoomsScrollBox.Components[i] as TEssence).Free;
      //(Form1.RoomsScrollBox.Components[i] as TEssence).disposeof;
      //(Form1.RoomsScrollBox.Components[i] as TEssence).parent:=nil;
      application.ProcessMessages;
    end
    else if Form1.RoomsScrollBox.Components[i] is TRele then
    begin
      (Form1.RoomsScrollBox.Components[i] as TRele).Parent := nil;
      (Form1.RoomsScrollBox.Components[i] as TRele).Free;
      application.ProcessMessages;
    end;
  end;

В Win все работает, а в Андроиде нет. Если ставлю Parent:=nil и Free, то не вызывается деструктор, если ставлю DisposeOf, то получаю ошибки при выполнении 

procedure TControl.MouseClick(Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
  if FPressed and not(FDoubleClick) and PointInObjectLocal(X, Y) then
  begin
    Click;
    FPressed := False;
    StartTriggerAnimation(Self, 'Pressed');
  end;
end;

Exception class Segmentation fault (11). 

и за ней Illegal instruction (4)

и программа зависает

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 час назад, gonzales сказал:

при нажатии на экземпляр класса должно произойти полное удаление всех элементов на Form1.RoomsScrollBox

Как вы считаете, удалять объект из самого этого объекта - это нормально?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Ну в общем то, задачка достаточно стандартная. И в win решается на раз. Вопрос, как это реализовать под Андроид. Вы не знаете случайно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
15 часов назад, gonzales сказал:

И в win решается на раз.

нет, совсем не на раз. Эта задача решается не совсем очевидным способом в том числе и на Windows (раз  два три , и это так - навскидку ). То, что вы не наткнулись на грабли в Windows - это очень хорошо. Вернее, плохо, потому что теперь вы считаете, что так делать можно. И потом возможны вопросы "вот почему раньше получалось, а с вот этим вот компонентом - нет".

Кросс-платформенные варианты:

Item.Release;
TThread.CreateAnonimousThread(... TThread.Queue(...здесь любой использованный вами ранее код удаления всех компонентов)).Start:

или аналог CreateAnonimousThread - TTask.Run

Изменено пользователем kami

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

по идее должно быть TThread.Queue, 
общая идея - нужно выйти из обработчика и потом (опять же в главном потоке!) поудалять все желаемое

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 час назад, krapotkin сказал:

по идее должно быть TThread.Queue, 

На самом деле без разницы, поскольку синхронизация с главным потоком (что Synchronize, что Queue) будут выполнены из вторичного потока только на Application.OnIdle (или что там есть у FMX Application). Но в общем - да, Queue звучит понятнее в данном контексте. Заменил.

А вот одну ошибку, про которую Ярослав рассказывал в статье "Жизненный цикл" мы чего-то упустили... Для анонимного потока нужна глобальная переменная:
 

var
   myThread: TThread;
...............
begin
  myThread:=TThread.CreateAnonimousThread(.здесь Synchronize или Queue с удалением компонентов..);
  myThread.Start;
end;

 

Изменено пользователем kami

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
Цитата

общая идея - нужно выйти из обработчика и потом (опять же в главном потоке!) поудалять все желаемое

krapotkin, kami Спасибо большое!  Буду разбираться.

Не затруднит ли выложить простой пример по использованию потока?

Заранее спасибо!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
TThread.Queue(NIL,procedure begin
  button1.parent:=nil;
  FreeAndNil(button1);
end);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

спасибо. Подскажите, правильно ли я запускаю поток

procedure TRoom.RoomClick(Sender: TObject);
//var
//  node: IXMLNode;
begin
  form1.myThread:=TThread.Create;
  form1.myThread.Queue(NIL,procedure begin
  (Sender as TRoom).parent:=nil;
  FreeAndNil(Sender as TRoom);
end);
  form1.myThread.Start;
end;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
procedure TForm1.RoomClick(Sender: TObject);
var r:TRoom absolute Sender;
begin
  TThread.Queue(NIL,procedure begin
    r.parent:=nil;
    FreeAndNil(r);
  end);
end

 

Изменено пользователем krapotkin

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

К сожалению данный код также не отрабатывает то, что нужно, деструктор не вызывается.

Вот код юнита. Вкратце, кнопка Button2 создает экземпляр класса TEssence, который имеет таймер. По таймеру перекрашивается rectangle1, который лежит на форме, по нажатию на объект, он должен удалиться. В Винде видим, что все отрабатывает, объект исчезает и таймер останавливается. В андроиде объект исчезает, а таймер продолжает работать((((

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, System.ImageList, FMX.ImgList,
  FMX.Objects;

type
  TEssence = class(TRectangle)
  private
    procedure EssenceMouseEnter(Sender: TObject);
    procedure EssenceMouseLeave(Sender: TObject);
    procedure EssenceClick(Sender: TObject);
  public
    EssenceName: TLabel;
    EssenceImage: TImage;
    ReleTimer : TTimer;
    constructor Create(AOwner: TComponent); Override;
    destructor Destroy; Override;
    procedure SetName(Name: string);
    procedure SetIcon(iconnumber: integer);
    procedure ReleOnTimer(Sender: TObject);

  end;


type
  TForm1 = class(TForm)
    Button2: TButton;
    ImageList1: TImageList;
    Rectangle1: TRectangle;
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

destructor TEssence.Destroy;
var
  i: integer;
begin
  EssenceImage.Release;
  EssenceName.Release;
  ReleTimer.Release;
  inherited;
end;

constructor TEssence.Create(AOwner: TComponent);
var
  Size: TSizeF;
begin
  inherited Create(AOwner);
  Parent := Form1;
  XRadius := 5;
  YRadius := 5;
  Stroke.Thickness := 1.2;
  Stroke.Color := 4286611584;
  Fill.Color := 4294967264;
  Margins.Top := 5;
  Margins.Bottom := 5;
  Margins.Left := 10;
  Margins.Right := 10;
  Align := TAlignLayout.Top;
  Position.Y := 1000;
  Height := 40;
  OnMouseEnter := self.EssenceMouseEnter;
  OnMouseLeave := self.EssenceMouseLeave;
  OnClick := self.EssenceClick;

  EssenceImage := TImage.Create(self);
  EssenceImage.Parent := self;
  EssenceImage.Align := TAlignLayout.Left;
  Size.cx := 20;
  Size.cy := 20;
  EssenceImage.Width := 22;
  EssenceImage.Margins.Left := 5;
  EssenceImage.Margins.Right := 0;
  EssenceImage.WrapMode := TImageWrapMode.Fit;
  EssenceImage.MarginWrapMode := TImageWrapMode.Original;
  EssenceImage.Locked := true;
  EssenceImage.HitTest := false;

  EssenceImage.Bitmap := Form1.ImageList1.Bitmap(Size, 1);

  EssenceName := TLabel.Create(self);
  EssenceName.Parent := self;
  EssenceName.Margins.Top := 5;
  EssenceName.Margins.Bottom := 5;
  EssenceName.Margins.Left := 5;
  EssenceName.Margins.Right := 10;
  EssenceName.Align := TAlignLayout.Client;
  EssenceName.StyledSettings := [TStyledSetting.Family];
  EssenceName.Font.Size := 16;
  EssenceName.FontColor := 4282477025;
  EssenceName.Text := 'Тест';
  EssenceName.WordWrap := false;
  EssenceName.Locked := true;
  EssenceImage.HitTest := false;

  ReleTimer := TTimer.Create(self);
  ReleTimer.Parent := self;
  ReleTimer.Interval := 500;
  ReleTimer.OnTimer := self.ReleOnTimer;
  ReleTimer.Enabled := true;
  // end;
end;

procedure TEssence.EssenceMouseEnter(Sender: TObject);
begin
  (Sender as TEssence).EssenceName.FontColor := 4294934352;
end;

procedure TEssence.EssenceMouseLeave(Sender: TObject);
begin
  (Sender as TEssence).EssenceName.FontColor := 4282477025;
end;

procedure TEssence.SetName(Name: string);
begin
  EssenceName.Text := name;
end;

procedure TEssence.ReleOnTimer(Sender: TObject);
begin
  if form1.Rectangle1.Fill.Color=4282477025 then
     form1.Rectangle1.Fill.Color:=4294934352
  else
    form1.Rectangle1.Fill.Color:=4282477025;

end;

procedure TEssence.SetIcon(iconnumber: integer);
var
  Size: TSizeF;
begin
  Size.cx := 20;
  Size.cy := 20;
  EssenceImage.Bitmap := Form1.ImageList1.Bitmap(Size, iconnumber);
end;

procedure TEssence.EssenceClick(Sender: TObject);
var r:TEssence absolute Sender;
begin
  TThread.Queue(NIL,procedure begin
    r.parent:=nil;
    FreeAndNil(r);
  end);
end;


procedure TForm1.Button2Click(Sender: TObject);
var
e:Tessence;
begin
  e:=TEssence.Create(form1);
  e.SetName('ntcn');
  e.SetIcon(1);
end;

end.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

А вот так работает. Все таки осталось загадкой, нужно ли использовать поток????

procedure TEssence.EssenceClick(Sender: TObject);
var r:TEssence absolute Sender;
begin
//  TThread.Queue(NIL,procedure begin
    r.Release;
//  end);
end;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Более того!!!

Я нашел причину странного поведения программы, но объяснения этому пока не вижу

вот так работает везде

procedure TEssence.EssenceClick(Sender: TObject);
var r:TEssence absolute Sender;
begin
    r.Release;
	
end;

а вот так только в винде

procedure TEssence.EssenceClick(Sender: TObject);
var r:TEssence absolute Sender;
begin
    r.Release;
	application.processmessages;  //ведет к segmentation fail в Android
end;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
5 часов назад, krapotkin сказал:

TThread.Queue(NIL,procedure begin   button1.parent:=nil;   FreeAndNil(button1); end);

Нет!

Queue, будучи вызванной из главного потока, выполнится сразу же, как будто анонимная функция является частью основного кода. Только через TTask.Run или CreateAnonimousThread.

1 час назад, gonzales сказал:

а вот так только в винде

А вот это из-за непонимания того, как работает Release, хотя частично я это объяснил ранее, да и по приведенным ранее ссылкам есть. Более того - Ярослав объяснял это в одной из тем на форуме, но увы - искать лень.

Итак, что делает Release:

1.а Сразу же ликвидирует объект отовсюду из FMX, где он мог быть зарегистрирован. Т.е. удаляются все ссылки на этот объект, которые могли присутствовать в стандартных модулях. Естественно, что если ваш код хранит ссылку (ссылки) на этот объект - вам нужно удалить их самостоятельно. Или же изначально помечать как weak.

1.б По завершению этого действа - объект помещается в специальное хранилище, так называемую "очередь на отложенное удаление".

1.в При этом сам объект еще жив и спокойно будет произведен выход из кода всех событий и методов, внутри которых он сейчас находится.

2. Когда приложение "бездельничает", вызывается очистка этой очереди, там объекту делают DisposeOf.

Вызов ProcessMessages элементарно может вызвать п.2. При этом пункт 1.в будет выполнен только после п.2, и то - с нарушениями, поскольку объект после выполнения 2 уже не жив.

Так понятнее?

Изменено пользователем kami

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
4 минуты назад, kami сказал:

Нет!

согласен. надо заменить на TTask.Run(...TThread.Synchronize()...)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
14 часа назад, gonzales сказал:

application.processmessages;

нельзя делать это в андроид. там нет сообщений на которые завязано это все в Windows

(на самом деле и в windows нельзя)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
Цитата

Итак, что делает Release:

Это я прочитал по ссылке, которую Вы выкладывали ранее. Просто использовал его с ProcessMessages, поэтому он не отрабатывал.

Цитата

Вызов ProcessMessages элементарно может вызвать п.2. При этом пункт 1.в будет выполнен только после п.2, и то - с нарушениями, поскольку объект после выполнения 2 уже не жив.

Это предположение, или утверждение? 

Цитата

нельзя делать это в андроид. там нет сообщений на которые завязано это все в Windows

тем не менее, application.processmessages отрабатывает в Андроид и во многих случаях правильно, это можно увидеть например при отрисовке массива объектов. Если после каждой отрисовки вставлять application.processmessages то объекты отрисовываются по одному, а если не вставлять, то отрисовка происходит один раз после создания последнего. Если их много, у пользователя создается ощущение, что программа зависла. Я с этим сталкивался, когда писал приложение для фотографий, processmessages замечательно себя показал. Почему здесь этого не произошло - загадка

 

Тем не менее, спасибо за советы, про release очень полезная была инфа, потому как раньше использовал DisposeOf, то бишь принудительное жесткое удаление. По потокам буду заниматься, мое кунг-фу еще не достаточно крутое для этого)))

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • -1
1 час назад, gonzales сказал:

Это я прочитал по ссылке, которую Вы выкладывали ранее. Просто использовал его с ProcessMessages, поэтому он не отрабатывал.

Значит, после прочтения не были сделаны выводы из числа тех, которые я расписал.

1 час назад, gonzales сказал:

Это предположение, или утверждение? 

Это утверждение.

1 час назад, gonzales сказал:

Почему здесь этого не произошло - загадка

Хм... даже после объяснений из (1.а) - (2) ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От gutalin79
      Почему при добавлении MapView в пример Android Service, приложение перестает работать?
      AndroidSimpleService.zip
       
       
       
      Пример делал по этому видео: 
       
    • От Astghik
      Hello !!!
      I want onButtonClick create popup. I use TPopup component. All good, but on android "Back button" click closing forma. But I want close popup (when popup is shown).

       
      //---------------------------------------------------------------------------------
      void __fastcall  btn3PointsClick(TObject *Sender)
      {
          PopUpSettings->IsOpen = true;
          PopUpSettings->PlacementTarget = btn3Points;
          PopUpSettings->BringToFront();
      }
      //-------------------------------------------------------------------------------------
      void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose)
      {
          try {
              if (PopUpSettings->IsOpen == true) {
                  CanClose = false;
              }
              else {
                  CanClose = true;
              }
          } __finally {
              PopUpSettings->IsOpen = false;
          }
      }
      //-------------------------------------------------------------------
       
    • От Rokweb
      Таймер с интервалом 1мс заметно подтормаживает во время выполнения анимации TFloatAnimation в Tokyo. У всех так или только у меня?
    • От Rokweb
      Здравствуйте.
      Речь пойдёт об Android.
      Использовал в Berlin данный unit для проигрывания звуков (TMediaPlayer не подходит) и все отлично работало. Сейчас перешел на Tokyo и происходит зависание в цикле:
       
      while not GLoaded do begin Sleep(10); Application.ProcessMessages; end;  
      Модуль прикрепил в сообщении.
       
      Так же интересует - возможно ли, использовать стиль, созданный в процессе разработки Android приложения - в iOS и если да - то как это правильно реализовать (почти каждый контрол имеет сейчас свой стиль)?
       
      Прошу помощи.
      GameAudioManager.zip
    • От zekelive
      Товарищи, здравствуйте. Хотел бы проконсультироваться с вами на довольно сложно для меня тему. Имеется клиентское мобильное приложение на Андроид. Принцип его просто, загружает фирмы из БД в scrollbox. За счёт того, что сразу загрузка всех данных из сервера занимает длительное время, было принято решение загружать с сервера только ключевую информацию (название фирмы), а остальную информацию загружать из локальной БД. При этом, т.к. файл БД можно легко вытащить из apk файла любому человеку, размещать всю БД на локалке нельзя. Только информацию в целом не представляющую большой значимости в отдельности от названия фирмы и не только. 
      Вопрос, правильная ли схему построения была выбрана с точки зрения защиты данных (если это так можно назвать), и оптимизации загрузки информации. 
      Приветствуются ваши советы, как лучше построить схему взаимодействия приложения с БД, или как лучше защитить данные. В идеале для быстродействия, загнать побольше данных в локальную БД. 
    • От Edward Tarasov
      Привет всем. кто сталкивался с такой ерундой, что в webbrowser вместо сайта тупо белый экран?? причем сам сайт отображаеться норм, и на том же планшете, но в стандартном бразуере и на компе... и именно этот сайт не пашет из приложения
    • От zekelive
      Друзья, первый раз столкнулся с картами и не пойму в чем дело. Приложение подписано, релизная версия. Добавил карты на форму и запустил на компиляцию, все отлично. Запускаю на смартфоне - приложение сразу вылетает. Ничего не прописывал связанное с картами, просто добавил компонент на форму. Что не так ?
    • От Алексей Алексеев
      Здравствуйте! Помогите начинающему, всё перелазил, всё что мог и всё безрезультатно.
      Такая проблема: 
      Стоит задача убрать перенос строки в Memo:
      Из 
      "1строка"
      "2строка" 
      сделать:
      "1строка 2строка" .
      Казалось бы все просто:
      memo1.Text:=memo1.Text.Replace(#13#10,' '); И на Windows всё работает, но на Android отказывается!
      Просто не реагирует, ошибок не выдает. Проверял на XE8 и на 10.2.
      Может дело в смартфоне Xiomi miMax? Так как вообще memo на нём глючит...
    • От gutalin79
      Доброго времени суток!
      Хотел у Вас спросить. Есть ли возможность сделать на Delphi под Android кнопку которая была бы доступна в режиме блокировки? То есть чтобы я мог её нажать и включить фонарик или ещё что-нибудь и при этом не пришлось разблокировать телефон. Заранее благодарю, за ответ!  

    • От brunnengi
      Здравствуйте.
      Требуется программа на андроид с набором кнопок со следующем функционалом:
      1. Кнопка1 - создать базу в test.sqlite (в том месте где доступ к нему есть только у самого приложения (имею ввиду если это не ROOT телефон, при рут и так всё понятно)
      2. Кнопка2 - создать таблицу в базе test.sqlite с названием "TblTest01" (с разным набором полей на своё усмотрение)
      3. Кнопка3 - создать таблицу в базе test.sqlite с названием "TblTest02" (с разным набором полей на своё усмотрение)
      4. Кнопка4 - Добавить строку в таблицу "TblTest01" (любой набор данных на ваших усмотрение)
      5. Кнопка5 - Удалить строку в таблице "TblTest01" (по любому ключу на ваше усмотрение)
      6. Кнопка6 - Изменить строку в таблице "TblTest01" (по любому ключу и любое значение на ваше усмотрение)
       
      Приложение должно иметь фоновый сервис, который должен получать данные с сервера и добавлять их в базу test.sqlite в таблицу "TblTest02".
      При получение новый данных, сервис должен показать в "шторке" сообщение, по клику на которую открывается само приложение с визуальной частью.
      Т.е. если визуально приложение закрыто, выгружено, не запущено или запущено, фоновый процесс должен сам делать запросы к серверу и добавлять новые данные в базу, если они есть/поступили
      Приложение должно запускаться вместе с системой, после перезагрузки и т.д.
      Использовать только те компоненты что доступны в самой среде из коробки.
      Часть где делается запрос к серверу должен иметь timeout равный 20 секундам.
      Сервис должен грамотно делать запросы к серверу как положено в Андроид приложениях. 
      Серверная часть мне не нужна, можете для теста сами эмулирвать эти процессы.
       
       
      -----
      ЦЕНА: 2500р.
      СРОКИ: Не горит, но в целом где то дней 7 есть
      Перечисляю на QIWI, ЯД, Сбербанк, короче куда скажите.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу