废话少说,如何使用KBMMW 做个过渡,使IOS 可以使用JAVA 的服务?
其实KBMMW 本身就要java service 的服务,但是为了把这个问题说清楚,我手工做一个例子。
首先,要使用JAVA 服务,JRE 是肯定要安装的。没有安装的话,自己去java.sun.com 去下载。
安装完毕, 命令行上运行 JAVA ,出现下图说明安装成功。
在服务器上首先祭起来JVM(JAVA 虚拟机)
function GetDllName: string;varRegistry: TRegistry;
Version:string;beginResult := 'jvm.dll';
Registry := TRegistry.Create(KEY_READ);tryRegistry.RootKey :=HKEY_LOCAL_MACHINE;if Registry.OpenKey('\SOFTWARE\JavaSoft\Java Runtime Environment', False) then
beginVersion := Registry.ReadString('CurrentVersion');if Version <> '' then
if Registry.OpenKey(Version, False) thenResult := Registry.ReadString('RuntimeLib');end;finallyRegistry.Free;end;end;procedureTForm1.Button3Click(Sender: TObject);varI: Integer;
WebResult,WebMessage: String;
n,e:integer;
VM_args:JavaVMInitArgs;
Options:array[0..20] ofJavaVMOption;
Methods:array [0..0] ofJNINativeMethod;
OptCnt:integer;
j_MainClass:JClass;
LibraryFileName:string;
Mid: JMethodID;
FObj,tmpobj: JObject;
FInit : JMethodID;
mypath:string;
myclasspath:ansistring;Env:PJNIEnv;
JNIEnv:TJNIEnv;constclasspath='.;';
JIT=True;begin
if G_javavm<>nil then
beginmeminfo.Lines.Add('JVM already created !');
exit;end;
n:=JNI_VERSION_1_4;
LibraryFileName:=GetDllName;
FillChar(Options,SizeOf(Options),#0);
OptCnt:=0;
mypath :=g_RootPath;
myclasspath:=classpath+mypath+'ws\ws.jar';
Options[OptCnt].optionString:=PAnsiChar('-Djava.class.path='+ myclasspath);
inc(OptCnt);if not JIT then
beginOptions[OptCnt].optionString:=PAnsiChar('-Djava.compiler=NONE');
inc(OptCnt);end;
VM_args.version:=n;
VM_args.options:= @Options ;//:= @Options;
VM_args.nOptions:=OptCnt;
VM_args.ignoreUnrecognized:=1;
g_JavaVM := TJavaVM.Create(n, LibraryFileName);
e :=G_JavaVM.LoadVM(VM_args);if e<0 then
beginmeminfo.Lines.Add ('Error loading JavaVM via JNI 1.4+. ErrorCode='+inttostr(e));
exit;end;
g_JNIEnv := TJNIEnv.Create(g_JavaVM.Env);
meminfo.Lines.Add('JVM create ok!');end;
当然了,文件里面必须引用 JNI 单元。这个是kbmmw 自带的(此文件原来是JEDI 翻译jni.h 得,后来kbmmw 作者修改了,可以在新版delphi 中编译);
安装完虚拟机,就可以在delphi 中使用java 的class 了
下面就是一个简单的封装java 中hashmap 的例子
1 Thashmap = class
2 private
3 FJNIEnv: TJNIEnv;4 FCls: JClass;5 FObj: JObject;6 FInit: JMethodID;7 FPut: JMethodID;8 FGet: JMethodID;9 public
10 constructor Create(JNIEnv:TJNIEnv;createobj:boolean=True);11 procedure put(ID,Text: string);12 Function get(ID: string):string;13 property hashmap: jobject read FObj writeFObj;14 end;15 {Thashmap}
16
17 constructor Thashmap.Create(JNIEnv: TJNIEnv; createobj: boolean);18 begin
19 inherited Create;20 FJNIEnv:=JNIEnv;21 if FJNIEnv=nil then
22 raise Exception.Create('Please create JNIEnv');23
24 FCls := FJNIEnv.FindClass('java/util/HashMap');25 if FCls=nil then
26 raise Exception.Create('can''t find class HashMap');27
28 FInit := FJNIEnv.GetMethodID(FCls, '', '()V');29 if FInit=nil then
30 raise Exception.Create('can''t find init in class HashMap');31
32 Fput := FJNIEnv.GetMethodID(FCls, 'put', '(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;');33
34 if Fput=nil then
35 raise Exception.Create('can''t find put in class HashMap');36
37 Fget := FJNIEnv.GetMethodID(FCls, 'get', '(Ljava/lang/Object;)Ljava/lang/Object;');38
39 if Fget=nil then
40 raise Exception.Create('can''t find get in class HashMap');41
42 if createobj then
43 begin
44 FObj :=FJNIEnv.NewObjectA(FCls, FInit, nil);45
46 if Fobj=nil then
47 raise Exception.Create('can''t create a HashMap');48 end;49 end;50
51 function Thashmap.get(ID: string): string;52 var
53 rets:Jstring;54 begin
55 rets:=FJNIEnv.CallObjectMethod( FObj,Fget,[FJNIEnv.StringToJString(id)]) ;56
57 result:=FJNIEnv.JStringToString(rets);58 end;59
60 procedure Thashmap.put(ID, Text: string);61 begin
62 FJNIEnv.CallObjectMethod( FObj,Fput,[FJNIEnv.StringToJString(id),FJNIEnv.StringToJString(text)]);63 end;
这样你就可以在delphi 中使用hashmap 了。
if myhashmap<>nil then
beginmemo1.Lines.Add('hashmap already create!!') ;
exit;end;
myhashmap :=Thashmap.Create(JNIEnv);
memo1.Lines.Add('HashMap create ok!!');
myhashmap.put('ROW_ID', ROW_ID);
myhashmap.put('BILL_ID', BILL_ID);
myhashmap.put('AUDIT_NODE', AUDIT_NODE);
myhashmap.put('AUDIT_STATUS', AUDIT_STATUS);
memo1.Lines.Add('put all data into hashmap');
memo1.Lines.Add('ROW_ID:'+ myhashmap.get('ROW_ID'));
memo1.Lines.Add('FLOW_ID:'+ myhashmap.get('FLOW_ID'));
那么由于kbmmw 是服务器端,肯定要考虑到多线程问题。
那么要在kbmmw servive 里面调用java 服务就要稍微处理一下。
示例如下:
functionTmysrv.JavaHashMapCheck(ClientIdent: TkbmMWClientIdentity;const Args: array ofVariant): Variant;varI: Integer;
ROW_ID,BILL_ID: String;
WebResult,WebMessage: String;
n,e:integer;
FObj,tmpobj, errorString: JObject;
rets:Jstring;myhashmap:Thashmap;Env:PJNIEnv;
JNIEnv:TJNIEnv;
throwable:JThrowable;
throwableClass:JClass;begin
Result := '';ROW_ID := Args[0];
BILL_ID := Args[1];G_JavaVM.JavaVM^.AttachCurrentThread(G_JavaVM.JavaVM,@Env,nil);tryJNIEnv:=TJNIEnv.Create(Env);
if myhashmap<>nil then
begin
Result := '0';
exit;end;
myhashmap :=Thashmap.Create(JNIEnv);myhashmap.put('ROW_ID', ROW_ID);
myhashmap.put('BILL_ID', BILL_ID);
result:='return='+myhashmap.get('ROW_ID');throwable:=JNIEnv.ExceptionOccurred();if throwable<>nil then
begin
tryJNIEnv.ExceptionDescribe;
throwableClass:=JNIEnv.GetObjectClass(throwable);if throwableClass<>nil then
beginmid:=JNIEnv.GetMethodID(throwableClass,'toString','()Ljava/lang/String;');if mid<>nil then
beginerrorString:=JNIEnv.CallObjectMethod(throwable,mid,[]);if errorString<>nil thenkbmMWRaiseException(KBMMW_ERR_SERVICE_JAVA_EXCEPTION,string(JNIEnv.JStringToString(errorString)));end;end;finallyJNIEnv.ExceptionClear;end;end;finallymyhashmap.Free;
myhashmap := nil;
tmphashmap.Free;
tmphashmap := nil;
myObjectUtil.Free;
myObjectUtil := nil;
JNIEnv.Free;
G_JavaVM.JavaVM^.DetachCurrentThread(G_JavaVM.JavaVM);end;end;
剩下的就是你自己处理了。
ios 里面按照老规矩调用kbmmw 服务就行了。