2016-01-04 3 views
0

Я делаю тестовое приложение с несколькими приложениями с Delphi xe8. Я прилагаю объектов к пунктам в ListBox следующим образом:Как извлечь исходное значение JString из списка в Android Kitkat Delphi XE8

unit Unit1; 

interface 

uses 
    System.SysUtils, System.Types, System.UITypes, System.Classes, 
    System.Variants, 

    FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics,  
    Androidapi.JNI.JavaTypes, FMX.Dialogs, 
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.ListBox,  
Androidapi.Helpers; 

type 
    TForm1 = class(TForm) 
    ListBox1: TListBox; 
    Button1: TButton; 
    Button2: TButton; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

    var 
    Form1: TForm1; 

    implementation 
    {$R *.fmx} 

    //this where I am Attaching objects to items 
    procedure TForm1.Button1Click(Sender: TObject); 
    var 
    str:string; 
    jstr1:JString; 
    begin 
    str:='apple'; 
    jstr1:=StringToJString(str); 
    ListBox1.Items.AddObject('fruit', TObject(jstr1)); 
    end; 


    //this where I am extracting the jstring objects 
    procedure TForm1.Button2Click(Sender: TObject); 
    var 
    jstr2:JString; 
    str2:string; 
    begin 
    jstr2:=JString(ListBox1.Items.Objects[i]); 
    str2:=JStringToString(jstr2); 
    showmessage('the fruit of the day is '+str2); 
    end; 

    end. 

Приведенный выше код работать нормально, и объекты jstring прикреплены к элементам, однако, когда я хочу извлечь объект jstring, который был прикреплен к вещь, я делаю это:

jstr2:=JString(ListBox1.Items.Objects[i]); 
//Above give me an AV: I get incompatible types TObject and JString 

str2:=JStringToString(jstr2); 

Приведенный выше код не компилируется из-за несовместимых типов TObject и JString. Но все же, если бы прикрепили строку в качестве объекта (вместо jstring) и хотел бы получить обратно эти строковые объекты я только мог сделать:

str2:=String(ListBox1.Items.Objects[i]); 

Это будет работать с регулярными строками. Как решить эту проблему, прикрепить и извлечь jstring?

+1

FWIW, AV является нарушением прав доступа и означает, что вы получаете доступ к памяти, которая не принадлежит программе, * во время выполнения *. Думаю, вы имели в виду ошибку компилятора во время компиляции? –

+0

Ваше сообщение об ошибке означает, что JString не является потомком TObject. Возможно, вы могли бы сохранить адрес JString, но я не знаком с тем, что такое JString, поэтому я неохотно говорю точно. –

ответ

0

Это всего лишь предложение, и я не могу проверить это (ничего не установлен здесь), но вы можете написать простой тип объекта и сохранить его (я помещаю его в свой собственный блок, который затем вы используете в своем модуле формы):

unit StringObjs; 

interface 

uses 
    Androidapi.JNI.JavaTypes; 

type 
    TStringObj = class 
    private 
    FPayload: string; 
    public 
    constructor Create(const Payload: JString); 
    class operator Explicit(const Obj: TStringObj): string; 
    end; 

implementation 

uses 
    Androidapi.Helpers; 

constructor TStringObj.Create(const Payload: JString); 
begin 
    FPayload := JStringToString(Payload); // store string, not JString! 
end; 

class operator TStringObj.Explicit(const Obj: TStringObj): string; 
begin 
    Result := Obj.FPlayload; 
end; 

end. 

и вы используете его в разделе реализации вашей формы устройства, как:

implementation 

uses ..., StringObjs; 

... 

    ListBox1.Items.AddObject('fruit', TStringObj.Create(jstr1)); 

и обратное:

MyString := string(ListBox1.Items[0] as TStringObj); 

Обратите внимание, что форма - это просто класс, но тот, который IDE знает и может редактировать с помощью конструктора форм. Чтобы объявить другие классы, сделайте что-то подобное, как я делаю выше. Прочтите Delphi Language Guide, чтобы узнать больше.

+0

Я поместил тип в свой блок и отредактировал свой ответ. Вы должны действительно узнать о классах и как объявлять и использовать их. См. Ссылку в моем ответе. –

+0

Объявление 'Создать' отличается от предыдущего объявления. Я считаю, что это причина, из-за которой «const» отсутствует в первом объявлении (в разделе интерфейса). Я добавил const, чтобы проверить, будет ли это работать, но это привело к ошибке, о которой я упоминал ранее «Undeclared FPayload». – megatr0n

+0

Отредактировано: добавлена ​​константа в объявлении Create. Вы можете попытаться понять код, а затем решить его самостоятельно. –