废话少说,如何使用KBMMW 做个过渡,使IOS 可以使用JAVA 的服务?
其实KBMMW 本身就要java service 的服务,但是为了把这个问题说清楚,我手工做一个例子。
首先,要使用JAVA 服务,JRE 是肯定要安装的。没有安装的话,自己去java.sun.com 去下载。
安装完毕, 命令行上运行 JAVA ,出现下图说明安装成功。
在服务器上首先祭起来JVM(JAVA 虚拟机)
function GetDllName: string; var Registry: TRegistry; Version: string; begin Result := ‘jvm.dll‘; Registry := TRegistry.Create(KEY_READ); try Registry.RootKey := HKEY_LOCAL_MACHINE; if Registry.OpenKey(‘\SOFTWARE\JavaSoft\Java Runtime Environment‘, False) then begin Version := Registry.ReadString(‘CurrentVersion‘); if Version <> ‘‘ then if Registry.OpenKey(Version, False) then Result := Registry.ReadString(‘RuntimeLib‘); end; finally Registry.Free; end; end; procedure TForm1.Button3Click(Sender: TObject); var I: Integer; WebResult,WebMessage: String; n,e:integer; VM_args:JavaVMInitArgs; Options:array[0..20] of JavaVMOption; Methods:array [0..0] of JNINativeMethod; OptCnt:integer; j_MainClass:JClass; LibraryFileName:string; Mid: JMethodID; FObj,tmpobj: JObject; FInit : JMethodID; mypath:string; myclasspath:ansistring; Env:PJNIEnv; JNIEnv:TJNIEnv; const classpath=‘.;‘; JIT=True; begin if G_javavm<>nil then begin meminfo.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 begin Options[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 begin meminfo.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 write FObj; 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, ‘<init>‘, ‘()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 begin memo1.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 服务就要稍微处理一下。
示例如下:
function Tmysrv.JavaHashMapCheck(ClientIdent: TkbmMWClientIdentity; const Args: array of Variant): Variant; var I: 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); try JNIEnv:=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 try JNIEnv.ExceptionDescribe; throwableClass:=JNIEnv.GetObjectClass(throwable); if throwableClass<>nil then begin mid:=JNIEnv.GetMethodID(throwableClass,‘toString‘,‘()Ljava/lang/String;‘); if mid<>nil then begin errorString:=JNIEnv.CallObjectMethod(throwable,mid,[]); if errorString<>nil then kbmMWRaiseException(KBMMW_ERR_SERVICE_JAVA_EXCEPTION,string(JNIEnv.JStringToString(errorString))); end; end; finally JNIEnv.ExceptionClear; end; end; finally myhashmap.Free; myhashmap := nil; tmphashmap.Free; tmphashmap := nil; myObjectUtil.Free; myObjectUtil := nil; JNIEnv.Free; G_JavaVM.JavaVM^.DetachCurrentThread(G_JavaVM.JavaVM); end; end;
剩下的就是你自己处理了。
ios 里面按照老规矩调用kbmmw 服务就行了。
时间: 2024-11-07 00:51:50