Jump to content

Миграция использования старого Android моста на новый


Всем доброго дня!

Как и обещал ранее, перед релизом 1.4.0.0 выкладываю инструкцию о миграции использования старого Android-Delphi моста на новый в 1.4.0.0. Это руководство актуально тем разработчикам, которые используют Android Api в своих проектах. В этой статье я рассмотрю только те аспекты в работе моста, которые изменились.

По большей части изменения были необходимы только в свете поддержки RAD Studio 10.4, в которой была полностью удалена поддержка модели памяти ARC.

1. Создание Java объекта:

Было:

var
  Intent: TJIntent;

Intent := TJIntent.Create;

Стало: 

var
  Intent: JIntent;

Intent := TJIntent.Create;

Все объявления переменных, атрибутов и тд должны быть теперь именованы без префикса "T". TJActivity -> JActivity.

2. Передача Java объектов через Java интерфейс:

Было:

// Декларация метода. Принимает атрибут интерфейсного типа CharSequence.
TJTextView.setError(const AArg0: JCharSequence);

// Java cтрока TJString реализует интерфейс JCharSequence. Поэтому передача идет напрямую (в старой версии моста).
View.setError(StringToJString(Control.Error));

Стало:

// Декларация метода. Принимает атрибут интерфейсного типа CharSequence.
TJTextView.setError(const AArg0: JCharSequence);

// Теперь обертка Java cтроки TJString НЕ реализует явно интерфейс JCharSequence. Поэтому необходима явная конвертация JString -> JCharSequence
View.setError(TJCharSequence.Wrap(StringToJString(Control.Error)));

// Или можно воспользоваться хелпером из FGX.Helpers.Android.pas
View.setError(StringToJCharSequence(Control.Error));

3. Работа с Java массивами:

При создании экземпляра Java массива (TJavaArray<T>) вся работа теперь осуществляется через интерфейс IJavaArray<T>.

Было:

var
  Points: TJavaArray<Single>;
 
Points := TJavaArray<Single>.Create(0);
FCanvas.drawLines(Points, FStroke);

Стало:

var
  Points: IJavaArray<Single>;
 
Points := TJavaArray<Single>.Create(0);
FCanvas.drawLines(Points, FStroke);

4. Работа с Java-листенерами:

Если вы реализовывали свои листенеры через наследование класса Java.Bridge.TJavaLocal, то в 1.4.0.0 листенеры теперь поддерживают счетчик ссылок через Delphi IInterface. Это значит, что при создании листенера, его необходимо сохранять в переменную/поле интерфейсного типа, а не объектного.

Было:

  TfgAndroidCameraStateListener = class(TJavaLocal, JCameraStateListener)
  private
    [Weak] FCamera: TfgAndroidCamera;
  public
    constructor Create(const ACamera: TfgAndroidCamera);
    { JCameraStateListener }
    procedure onClosed(const AArg0: JCameraDevice);
    procedure onDisconnected(const cameraDevice: JCameraDevice);
    procedure onError(const cameraDevice: JCameraDevice; const errorCode: Integer);
    procedure onOpened(const cameraDevice: JCameraDevice);
  end;

var
  FStateListener: TfgAndroidCameraStateListener

FStateListener := TfgAndroidCameraStateListener.Create(Self);
FStateCallback.setListener(FStateListener);

Стало:

  TfgAndroidCameraStateListener = class(TJavaLocal, JCameraStateListener)
  private
    [Weak] FCamera: TfgAndroidCamera;
  public
    constructor Create(const ACamera: TfgAndroidCamera);
    { JCameraStateListener }
    procedure onClosed(const AArg0: JCameraDevice);
    procedure onDisconnected(const cameraDevice: JCameraDevice);
    procedure onError(const cameraDevice: JCameraDevice; const errorCode: Integer);
    procedure onOpened(const cameraDevice: JCameraDevice);
  end;

var
  FStateListener: JCameraStateListener

FStateListener := TfgAndroidCameraStateListener.Create(Self);
FStateCallback.setListener(FStateListener);

В противном случае, экземпляр листенера FStateListener будет удален сразу же после вызова 

FStateCallback.setListener(FStateListener);

Что в свою очередь приведет к последующим падения приложения. Так как сработает механизм подсчета ссылок Delphi интерфейсов. 

5. Конвертация string <-> JString:

До RAD Studio 10.4 мобильные компиляторы поддерживали добавление операторов неявного преобразования. Это в свою очередь позволило нам реализовать автоматическую конвертацию "на лету" Delphi string <-> Java JString. В 10.4 эту возможность убрали вместе с ARC, так как неявное преобразование реализуется через ARC. Поэтому теперь нужно явно вызывать преобразование строк через StringToJString и JStringToString:

Было:

TjUri.parse('tel:+');

Стало:

uses
  FGX.Helpers.Android;

TJUri.parse(StringToJString('tel:+'))

Это все изменения, которые необходимо сделать.

2 Comments


Recommended Comments

mahmoudikia

Posted

Hi

Is it possible to convert TArray<String> to IJavaArray<JString>

  • Administrators
Yaroslav Brovin

Posted

Yes, we have helper for it FGX.Helpers.Android:

{ Array utils }

function CreateJavaStringArray(const ASource: array of string): IJavaArray<JString>;
function CreateJavaObjectArray(const ASource: array of const): IJavaArray<JObject>;
function CreateJavaIntegerArray(const ASource: array of Integer): IJavaArray<Integer>;
function CreateJavaSingleArray(const ASource: array of Single): IJavaArray<Single>;
function CreateJavaByteArray(const ASource: TStream): IJavaArray<Byte>; overload;
function CreateJavaByteArray(const AData: Pointer; const ASize: Integer): IJavaArray<Byte>; overload;

function JavaArrayToIntArray(const AJavaArray: IJavaArray<Integer>): TArray<Integer>;
function JavaArrayToByteArray(const AJavaArray: IJavaArray<Byte>): TArray<Byte>;
function JavaSizeArrayToSizeArray(const AJavaArray: IJavaArray<JSize>): TArray<TSize>;

 

  • Like 1
Guest
Add a comment...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...