如何从 Android Kitkat Delphi XE8 中的列表框中提取原始 JString 值
How to extract original JString value from Listbox in Android Kitkat Delphi XE8
我正在使用 Delphi xe8 测试 android 多设备应用程序。我将对象附加到列表框中的项目,如下所示:
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.
上面的代码运行 ok并且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?
这只是一个建议,我不能检查这个(这里没有安装任何东西),但你可以写一个简单的对象类型并存储它(我把它放在它自己的单元中,然后你在你的表单中使用它单位):
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);
请注意,表单只是 class,但 IDE 知道并且可以使用表单设计器进行编辑。要声明其他 classes,请执行与我上面类似的操作。阅读 Delphi Language Guide 以了解更多信息。
我正在使用 Delphi xe8 测试 android 多设备应用程序。我将对象附加到列表框中的项目,如下所示:
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.
上面的代码运行 ok并且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?
这只是一个建议,我不能检查这个(这里没有安装任何东西),但你可以写一个简单的对象类型并存储它(我把它放在它自己的单元中,然后你在你的表单中使用它单位):
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);
请注意,表单只是 class,但 IDE 知道并且可以使用表单设计器进行编辑。要声明其他 classes,请执行与我上面类似的操作。阅读 Delphi Language Guide 以了解更多信息。